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
81 #include "CedarPch.h"
\r
83 static CLIENT *client = NULL;
\r
84 static LISTENER *cn_listener = NULL;
\r
85 static LOCK *cn_listener_lock = NULL;
\r
86 static UINT64 cn_next_allow = 0;
\r
92 // 注意: VPN Client サービスを実装するこのソースコードの一部には、
\r
93 // リエントラント (Reentrant: 再入可能) でないコードが含まれている。
\r
94 // もともと VPN Client のサービスと GUI (クライアント接続マネージャ) は一体
\r
95 // のものとして開発され、途中で分離された。その際に本来であれば TLS 等を用いて
\r
96 // スレッドセーフにしなければならない部分が、もとのままになってしまっている。
\r
97 // したがって、ごくまれに、GUI (クライアント接続マネージャ) や utvpncmd が
\r
98 // 複数個、1 個の VPN Client サービスに対して接続して、ほぼ同時に何らかの
\r
99 // 内部状態を変化させる処理を行ったとき、戻り値に不整合が生じる場合がある。
\r
101 // RPC_CLIENT_ENUM_ACCOUNT_ITEM を最終接続日時で逆ソート
\r
102 int CiCompareClientAccountEnumItemByLastConnectDateTime(void *p1, void *p2)
\r
104 RPC_CLIENT_ENUM_ACCOUNT_ITEM *a1, *a2;
\r
105 if (p1 == NULL || p2 == NULL)
\r
109 a1 = *(RPC_CLIENT_ENUM_ACCOUNT_ITEM **)p1;
\r
110 a2 = *(RPC_CLIENT_ENUM_ACCOUNT_ITEM **)p2;
\r
111 if (a1 == NULL || a2 == NULL)
\r
115 if (a1->LastConnectDateTime > a2->LastConnectDateTime)
\r
119 else if (a1->LastConnectDateTime < a2->LastConnectDateTime)
\r
127 // マシンが変更されていた場合はすべての仮想 LAN カードの MAC アドレスを乱数に設定する
\r
128 // このあたりは急いで実装したのでコードがあまり美しくない。
\r
129 // Q. なぜこのような処理が必要なのか?
\r
130 // A. Windows をインストールし、次に VPN Client をインストールして仮想 LAN カード
\r
131 // を作成した状態を初期状態として HDD イメージをクローンし社内の複数の PC に
\r
132 // インストールするような企業が存在する。
\r
133 // そのような企業においてクローン後も仮想 LAN カードの MAC アドレスがすべて同一
\r
134 // であれば障害の理由になる可能性があるためである。
\r
135 void CiChangeAllVLanMacAddressIfMachineChanged(CLIENT *c)
\r
137 UCHAR current_hash[SHA1_SIZE];
\r
138 UCHAR current_hash_old[SHA1_SIZE];
\r
139 UCHAR saved_hash[SHA1_SIZE];
\r
147 if (MsIsAdmin() == false)
\r
153 // このあたりは急いで実装したのでコードがあまり美しくない。
\r
154 CiGetCurrentMachineHash(current_hash);
\r
155 CiGetCurrentMachineHashOld(current_hash_old);
\r
157 if (CiReadLastMachineHash(saved_hash) == false)
\r
159 CiWriteLastMachineHash(current_hash);
\r
163 if (Cmp(saved_hash, current_hash_old, SHA1_SIZE) == 0)
\r
165 CiWriteLastMachineHash(current_hash);
\r
169 if (Cmp(saved_hash, current_hash, SHA1_SIZE) == 0)
\r
174 if (CiWriteLastMachineHash(current_hash) == false)
\r
179 CiChangeAllVLanMacAddress(c);
\r
182 // 現在のマシンハッシュを取得する (古い方式)
\r
183 // このあたりは急いで実装したのでコードがあまり美しくない。
\r
184 void CiGetCurrentMachineHashOld(void *data)
\r
186 char name[MAX_PATH];
\r
187 char *product_id = NULL;
\r
196 product_id = MsRegReadStr(REG_LOCAL_MACHINE, "SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion", "ProductId");
\r
197 if (product_id == NULL)
\r
199 product_id = MsRegReadStr(REG_LOCAL_MACHINE, "SOFTWARE\\Microsoft\\Windows\\CurrentVersion", "ProductId");
\r
202 StrCpy(name, sizeof(name), product_id);
\r
207 GetMachineName(name, sizeof(name));
\r
213 Hash(data, name, StrLen(name), true);
\r
217 void CiGetCurrentMachineHash(void *data)
\r
219 char name[MAX_PATH];
\r
220 char *product_id = NULL;
\r
227 GetMachineName(name, sizeof(name));
\r
232 Hash(data, name, StrLen(name), true);
\r
236 bool CiWriteLastMachineHash(void *data)
\r
245 if (MsRegWriteBinEx(REG_LOCAL_MACHINE, MS_REG_TCP_SETTING_KEY, "LastMachineHash_UTVPNClient", data, SHA1_SIZE, true) == false)
\r
257 bool CiReadLastMachineHash(void *data)
\r
267 b = MsRegReadBinEx(REG_LOCAL_MACHINE, MS_REG_TCP_SETTING_KEY, "LastMachineHash_UTVPNClient", true);
\r
272 if (b->Size == SHA1_SIZE)
\r
274 Copy(data, b->Buf, b->Size);
\r
287 // すべての仮想 LAN カードの MAC アドレスを乱数に設定する
\r
288 void CiChangeAllVLanMacAddress(CLIENT *c)
\r
290 RPC_CLIENT_ENUM_VLAN t;
\r
297 Zero(&t, sizeof(t));
\r
298 if (CtEnumVLan(c, &t))
\r
302 for (i = 0;i < t.NumItem;i++)
\r
304 RPC_CLIENT_ENUM_VLAN_ITEM *e = t.Items[i];
\r
307 if (StrToMac(mac, e->MacAddress) && mac[1] == 0xAC)
\r
309 char *name = e->DeviceName;
\r
310 RPC_CLIENT_SET_VLAN s;
\r
313 GenMacAddress(mac);
\r
315 Zero(&s, sizeof(s));
\r
316 StrCpy(s.DeviceName, sizeof(s.DeviceName), name);
\r
318 MacToStr(s.MacAddress, sizeof(s.MacAddress), mac);
\r
324 CiFreeClientEnumVLan(&t);
\r
328 // 通知サービスの準備が完了するまで待機する
\r
329 void CnWaitForCnServiceReady()
\r
331 UINT64 start_time = Tick64();
\r
333 while ((start_time + (UINT64)CLIENT_WAIT_CN_READY_TIMEOUT) >= Tick64())
\r
335 if (CnIsCnServiceReady())
\r
344 // 通知サービスの準備が完了しているかどうかチェックする
\r
345 // このあたりは急いで実装したのでコードがあまり美しくない。
\r
346 bool CnIsCnServiceReady()
\r
350 if (CnCheckAlreadyExists(false) == false)
\r
356 // TCP ポートへの接続を試行する
\r
357 s = ConnectEx("localhost", CLIENT_NOTIFY_PORT, 500);
\r
371 // すでに通知サービスが動作しているかどうかチェックする
\r
372 bool CnCheckAlreadyExists(bool lock)
\r
377 ret = Win32CnCheckAlreadyExists(lock);
\r
383 typedef struct CNC_STATUS_PRINTER_WINDOW_PARAM
\r
388 } CNC_STATUS_PRINTER_WINDOW_PARAM;
\r
390 typedef struct CNC_CONNECT_ERROR_DLG_THREAD_PARAM
\r
396 } CNC_CONNECT_ERROR_DLG_THREAD_PARAM;
\r
399 // Win32 における utvpnclient.exe のファイル名を取得する
\r
400 char *CiGetVpnClientExeFileName()
\r
402 if (Is64() == false)
\r
404 return CLIENT_WIN32_EXE_FILENAME;
\r
410 return CLIENT_WIN32_EXE_FILENAME_X64;
\r
414 return CLIENT_WIN32_EXE_FILENAME_IA64;
\r
419 // 証明書チェックダイアログクライアント強制停止用スレッド
\r
420 void CncCheckCertHaltThread(THREAD *thread, void *param)
\r
422 CNC_CONNECT_ERROR_DLG_THREAD_PARAM *dp = (CNC_CONNECT_ERROR_DLG_THREAD_PARAM *)param;
\r
424 if (thread == NULL || param == NULL)
\r
431 if (dp->Session->Halt || dp->HaltThread)
\r
436 Wait(dp->Event, 100);
\r
439 Disconnect(dp->Sock);
\r
443 void CncCheckCert(SESSION *session, UI_CHECKCERT *dlg)
\r
447 CNC_CONNECT_ERROR_DLG_THREAD_PARAM *dp;
\r
450 if (dlg == NULL || session == NULL)
\r
462 PackAddStr(p, "function", "check_cert");
\r
463 PackAddUniStr(p, "AccountName", dlg->AccountName);
\r
464 PackAddStr(p, "ServerName", dlg->ServerName);
\r
465 PackAddX(p, "x", dlg->x);
\r
466 PackAddX(p, "parent_x", dlg->parent_x);
\r
467 PackAddX(p, "old_x", dlg->old_x);
\r
468 PackAddBool(p, "DiffWarning", dlg->DiffWarning);
\r
469 PackAddBool(p, "Ok", dlg->Ok);
\r
470 PackAddBool(p, "SaveServerCert", dlg->SaveServerCert);
\r
475 dp = ZeroMalloc(sizeof(CNC_CONNECT_ERROR_DLG_THREAD_PARAM));
\r
477 dp->Event = NewEvent();
\r
478 dp->Session = session;
\r
480 t = NewThread(CncCheckCertHaltThread, dp);
\r
485 dlg->Ok = PackGetBool(p, "Ok");
\r
486 dlg->DiffWarning = PackGetBool(p, "DiffWarning");
\r
487 dlg->SaveServerCert = PackGetBool(p, "SaveServerCert");
\r
492 dp->HaltThread = true;
\r
495 WaitThread(t, INFINITE);
\r
497 ReleaseEvent(dp->Event);
\r
506 bool CncSecureSignDlg(SECURE_SIGN *sign)
\r
524 PackAddStr(p, "function", "secure_sign");
\r
525 OutRpcSecureSign(p, sign);
\r
533 ret = PackGetBool(p, "ret");
\r
537 FreeRpcSecureSign(sign);
\r
539 Zero(sign, sizeof(SECURE_SIGN));
\r
540 InRpcSecureSign(sign, p);
\r
553 SOCK *CncNicInfo(UI_NICINFO *info)
\r
564 s = CncConnectEx(200);
\r
571 PackAddStr(p, "function", "nicinfo");
\r
572 PackAddStr(p, "NicName", info->NicName);
\r
573 PackAddUniStr(p, "AccountName", info->AccountName);
\r
582 void CncNicInfoFree(SOCK *s)
\r
595 SOCK *CncMsgDlg(UI_MSG_DLG *dlg)
\r
607 s = CncConnectEx(200);
\r
614 PackAddStr(p, "function", "msg_dialog");
\r
615 PackAddStr(p, "ServerName", dlg->ServerName);
\r
616 PackAddStr(p, "HubName", dlg->HubName);
\r
617 utf = CopyUniToUtf(dlg->Msg);
\r
618 PackAddData(p, "Msg", utf, StrLen(utf));
\r
628 void CndMsgDlgFree(SOCK *s)
\r
640 // パスワード入力ダイアログクライアント強制停止用スレッド
\r
641 void CncPasswordDlgHaltThread(THREAD *thread, void *param)
\r
643 CNC_CONNECT_ERROR_DLG_THREAD_PARAM *dp = (CNC_CONNECT_ERROR_DLG_THREAD_PARAM *)param;
\r
645 if (thread == NULL || param == NULL)
\r
652 if (dp->Session->Halt || dp->HaltThread)
\r
657 Wait(dp->Event, 100);
\r
660 Disconnect(dp->Sock);
\r
664 bool CncPasswordDlg(SESSION *session, UI_PASSWORD_DLG *dlg)
\r
668 CNC_CONNECT_ERROR_DLG_THREAD_PARAM *dp;
\r
672 if (dlg == NULL || session == NULL)
\r
680 Wait(session->HaltEvent, session->RetryInterval);
\r
685 PackAddStr(p, "function", "password_dialog");
\r
686 PackAddInt(p, "Type", dlg->Type);
\r
687 PackAddStr(p, "Username", dlg->Username);
\r
688 PackAddStr(p, "Password", dlg->Password);
\r
689 PackAddStr(p, "ServerName", dlg->ServerName);
\r
690 PackAddInt(p, "RetryIntervalSec", dlg->RetryIntervalSec);
\r
691 PackAddBool(p, "ProxyServer", dlg->ProxyServer);
\r
692 PackAddBool(p, "AdminMode", dlg->AdminMode);
\r
693 PackAddBool(p, "ShowNoSavePassword", dlg->ShowNoSavePassword);
\r
694 PackAddBool(p, "NoSavePassword", dlg->NoSavePassword);
\r
699 dp = ZeroMalloc(sizeof(CNC_CONNECT_ERROR_DLG_THREAD_PARAM));
\r
700 dp->Session = session;
\r
702 dp->Event = NewEvent();
\r
704 t = NewThread(CncConnectErrorDlgHaltThread, dp);
\r
709 ret = PackGetBool(p, "ok");
\r
710 dlg->NoSavePassword = PackGetBool(p, "NoSavePassword");
\r
711 dlg->ProxyServer = PackGetBool(p, "ProxyServer");
\r
712 dlg->Type = PackGetInt(p, "Type");
\r
713 PackGetStr(p, "Username", dlg->Username, sizeof(dlg->Username));
\r
714 PackGetStr(p, "Password", dlg->Password, sizeof(dlg->Password));
\r
719 dp->HaltThread = true;
\r
722 WaitThread(t, INFINITE);
\r
724 ReleaseEvent(dp->Event);
\r
734 // 接続エラーダイアログクライアント強制停止用スレッド
\r
735 void CncConnectErrorDlgHaltThread(THREAD *thread, void *param)
\r
737 CNC_CONNECT_ERROR_DLG_THREAD_PARAM *dp = (CNC_CONNECT_ERROR_DLG_THREAD_PARAM *)param;
\r
739 if (thread == NULL || param == NULL)
\r
746 if (dp->Session->Halt || dp->HaltThread)
\r
751 Wait(dp->Event, 100);
\r
754 Disconnect(dp->Sock);
\r
758 bool CncConnectErrorDlg(SESSION *session, UI_CONNECTERROR_DLG *dlg)
\r
762 CNC_CONNECT_ERROR_DLG_THREAD_PARAM *dp;
\r
766 if (dlg == NULL || session == NULL)
\r
774 Wait(session->HaltEvent, session->RetryInterval);
\r
779 PackAddStr(p, "function", "connecterror_dialog");
\r
780 PackAddUniStr(p, "AccountName", dlg->AccountName);
\r
781 PackAddStr(p, "ServerName", dlg->ServerName);
\r
782 PackAddInt(p, "Err", dlg->Err);
\r
783 PackAddInt(p, "CurrentRetryCount", dlg->CurrentRetryCount);
\r
784 PackAddInt(p, "RetryLimit", dlg->RetryLimit);
\r
785 PackAddInt(p, "RetryIntervalSec", dlg->RetryIntervalSec);
\r
786 PackAddBool(p, "HideWindow", dlg->HideWindow);
\r
791 dp = ZeroMalloc(sizeof(CNC_CONNECT_ERROR_DLG_THREAD_PARAM));
\r
792 dp->Session = session;
\r
794 dp->Event = NewEvent();
\r
796 t = NewThread(CncConnectErrorDlgHaltThread, dp);
\r
801 ret = PackGetBool(p, "ok");
\r
802 dlg->HideWindow = PackGetBool(p, "HideWindow");
\r
807 dp->HaltThread = true;
\r
810 WaitThread(t, INFINITE);
\r
812 ReleaseEvent(dp->Event);
\r
822 // ステータス表示器クライアント用スレッド
\r
823 void CncStatusPrinterWindowThreadProc(THREAD *thread, void *param)
\r
825 CNC_STATUS_PRINTER_WINDOW_PARAM *pp;
\r
829 if (thread == NULL || param == NULL)
\r
834 pp = (CNC_STATUS_PRINTER_WINDOW_PARAM *)param;
\r
836 pp->Thread = thread;
\r
837 AddRef(pp->Thread->ref);
\r
839 NoticeThreadInit(thread);
\r
841 p = RecvPack(sock);
\r
845 StopSessionEx(pp->Session, true);
\r
851 // ステータス表示器クライアントの作成
\r
852 SOCK *CncStatusPrinterWindowStart(SESSION *s)
\r
857 CNC_STATUS_PRINTER_WINDOW_PARAM *param;
\r
864 sock = CncConnect();
\r
872 PackAddStr(p, "function", "status_printer");
\r
873 PackAddUniStr(p, "account_name", s->Account->ClientOption->AccountName);
\r
875 if (SendPack(sock, p) == false)
\r
885 param = ZeroMalloc(sizeof(CNC_STATUS_PRINTER_WINDOW_PARAM));
\r
886 param->Sock = sock;
\r
887 param->Session = s;
\r
889 sock->Param = param;
\r
891 t = NewThread(CncStatusPrinterWindowThreadProc, param);
\r
899 // ステータス表示器に対して文字列を送信
\r
900 void CncStatusPrinterWindowPrint(SOCK *s, wchar_t *str)
\r
902 CNC_STATUS_PRINTER_WINDOW_PARAM *param;
\r
905 if (s == NULL || str == NULL)
\r
910 param = (CNC_STATUS_PRINTER_WINDOW_PARAM *)s->Param;
\r
913 PackAddUniStr(p, "string", str);
\r
918 // ステータス表示器クライアントの停止
\r
919 void CncStatusPrinterWindowStop(SOCK *s)
\r
921 CNC_STATUS_PRINTER_WINDOW_PARAM *param;
\r
928 param = (CNC_STATUS_PRINTER_WINDOW_PARAM *)s->Param;
\r
934 WaitThread(param->Thread, INFINITE);
\r
935 ReleaseThread(param->Thread);
\r
941 // Windows Vista 用のドライバインストーラの起動
\r
942 bool CncExecDriverInstaller(char *arg)
\r
944 SOCK *s = CncConnect();
\r
953 PackAddStr(p, "function", "exec_driver_installer");
\r
954 PackAddStr(p, "arg", arg);
\r
967 ret = PackGetBool(p, "ret");
\r
977 // 現在動作しているクライアント通知サービスにソケットを解放させる
\r
978 void CncReleaseSocket()
\r
980 SOCK *s = CncConnect();
\r
988 PackAddStr(p, "function", "release_socket");
\r
991 PackAddInt(p, "pid", MsGetProcessId());
\r
1001 // クライアント通知サービスのセッション ID の取得
\r
1002 UINT CncGetSessionId()
\r
1004 SOCK *s = CncConnect();
\r
1013 PackAddStr(p, "function", "get_session_id");
\r
1026 ret = PackGetInt(p, "session_id");
\r
1036 // クライアント通知サービスのプロセスの終了
\r
1039 SOCK *s = CncConnectEx(256);
\r
1044 PackAddStr(p, "function", "exit");
\r
1050 FreePack(RecvPack(s));
\r
1057 MsKillOtherInstanceEx("utvpnclient");
\r
1058 #endif // OS_WIN32
\r
1061 // クライアント通知サービスへの接続
\r
1062 SOCK *CncConnect()
\r
1064 return CncConnectEx(0);
\r
1066 SOCK *CncConnectEx(UINT timeout)
\r
1068 SOCK *s = ConnectEx("localhost", CLIENT_NOTIFY_PORT, timeout);
\r
1075 // 証明書チェックダイアログ用スレッド
\r
1076 void Win32CnCheckCertThreadProc(THREAD *thread, void *param)
\r
1078 UI_CHECKCERT *dlg;
\r
1080 if (thread == NULL || param == NULL)
\r
1085 dlg = (UI_CHECKCERT *)param;
\r
1087 CheckCertDlg(dlg);
\r
1089 PACK *p = NewPack();
\r
1091 PackAddBool(p, "Ok", dlg->Ok);
\r
1092 PackAddBool(p, "SaveServerCert", dlg->SaveServerCert);
\r
1094 SendPack(dlg->Sock, p);
\r
1097 FreePack(RecvPack(dlg->Sock));
\r
1100 Disconnect(dlg->Sock);
\r
1104 void Win32CnCheckCert(SOCK *s, PACK *p)
\r
1108 Zero(&dlg, sizeof(dlg));
\r
1110 if (s == NULL || p == NULL)
\r
1115 PackGetUniStr(p, "AccountName", dlg.AccountName, sizeof(dlg.AccountName));
\r
1116 PackGetStr(p, "ServerName", dlg.ServerName, sizeof(dlg.ServerName));
\r
1117 dlg.x = PackGetX(p, "x");
\r
1118 dlg.parent_x = PackGetX(p, "parent_x");
\r
1119 dlg.old_x = PackGetX(p, "old_x");
\r
1120 dlg.DiffWarning = PackGetBool(p, "DiffWarning");
\r
1121 dlg.Ok = PackGetBool(p, "Ok");
\r
1122 dlg.SaveServerCert = PackGetBool(p, "SaveServerCert");
\r
1125 t = NewThread(Win32CnCheckCertThreadProc, &dlg);
\r
1127 FreePack(RecvPack(s));
\r
1131 WaitThread(t, INFINITE);
\r
1134 FreeX(dlg.parent_x);
\r
1139 // メッセージ表示ダイアログスレッドプロシージャ
\r
1140 void Win32CnMsgDlgThreadProc(THREAD *thread, void *param)
\r
1142 UI_MSG_DLG *dlg = (UI_MSG_DLG *)param;
\r
1143 wchar_t tmp[MAX_SIZE];
\r
1144 char url[MAX_SIZE];
\r
1146 if (thread == NULL || dlg == NULL)
\r
1151 UniFormat(tmp, sizeof(tmp), _UU("CM_MSG_TITLE"),
\r
1152 dlg->ServerName, dlg->HubName);
\r
1154 if (IsURLMsg(dlg->Msg, url, sizeof(url)) == false)
\r
1156 OnceMsgEx(NULL, tmp, dlg->Msg, true, 167, &dlg->Halt);
\r
1160 if (MsExecute(url, NULL) == false)
\r
1162 OnceMsgEx(NULL, tmp, dlg->Msg, true, 167, &dlg->Halt);
\r
1166 Disconnect(dlg->Sock);
\r
1169 // NIC 情報ダイアログスレッドプロシージャ
\r
1170 void Win32CnNicInfoThreadProc(THREAD *thread, void *param)
\r
1172 UI_NICINFO *info = (UI_NICINFO *)param;
\r
1174 if (thread == NULL || info == NULL)
\r
1181 // Windows 9x 系ではダイアログを表示しない
\r
1185 Disconnect(info->Sock);
\r
1189 void Win32CnNicInfo(SOCK *s, PACK *p)
\r
1193 Zero(&info, sizeof(info));
\r
1195 if (s == NULL || p == NULL)
\r
1200 PackGetStr(p, "NicName", info.NicName, sizeof(info.NicName));
\r
1201 PackGetUniStr(p, "AccountName", info.AccountName, sizeof(info.AccountName));
\r
1205 t = NewThread(Win32CnNicInfoThreadProc, &info);
\r
1207 FreePack(RecvPack(s));
\r
1211 WaitThread(t, INFINITE);
\r
1216 void Win32CnMsgDlg(SOCK *s, PACK *p)
\r
1223 Zero(&dlg, sizeof(dlg));
\r
1225 if (s == NULL || p == NULL)
\r
1230 PackGetStr(p, "ServerName", dlg.ServerName, sizeof(dlg.ServerName));
\r
1231 PackGetStr(p, "HubName", dlg.HubName, sizeof(dlg.HubName));
\r
1233 utf_size = PackGetDataSize(p, "Msg");
\r
1234 utf = ZeroMalloc(utf_size + 8);
\r
1236 PackGetData(p, "Msg", utf);
\r
1238 msg = CopyUtfToUni(utf);
\r
1244 t = NewThread(Win32CnMsgDlgThreadProc, &dlg);
\r
1246 FreePack(RecvPack(s));
\r
1250 WaitThread(t, INFINITE);
\r
1256 // パスワード入力ダイアログ用スレッド
\r
1257 void Win32CnPasswordDlgThreadProc(THREAD *thread, void *param)
\r
1259 UI_PASSWORD_DLG *dlg;
\r
1261 if (thread == NULL || param == NULL)
\r
1266 dlg = (UI_PASSWORD_DLG *)param;
\r
1268 if (PasswordDlg(NULL, dlg))
\r
1270 PACK *p = NewPack();
\r
1272 PackAddBool(p, "ok", true);
\r
1273 PackAddStr(p, "Username", dlg->Username);
\r
1274 PackAddStr(p, "Password", dlg->Password);
\r
1275 PackAddInt(p, "Type", dlg->Type);
\r
1276 PackAddBool(p, "ProxyServer", dlg->ProxyServer);
\r
1277 PackAddBool(p, "NoSavePassword", dlg->NoSavePassword);
\r
1279 SendPack(dlg->Sock, p);
\r
1282 FreePack(RecvPack(dlg->Sock));
\r
1285 Disconnect(dlg->Sock);
\r
1289 void Win32CnPasswordDlg(SOCK *s, PACK *p)
\r
1291 UI_PASSWORD_DLG dlg;
\r
1293 Zero(&dlg, sizeof(dlg));
\r
1295 if (s == NULL || p == NULL)
\r
1300 dlg.Type = PackGetInt(p, "Type");
\r
1301 PackGetStr(p, "Username", dlg.Username, sizeof(dlg.Username));
\r
1302 PackGetStr(p, "Password", dlg.Password, sizeof(dlg.Password));
\r
1303 PackGetStr(p, "ServerName", dlg.ServerName, sizeof(dlg.ServerName));
\r
1304 dlg.RetryIntervalSec = PackGetInt(p, "RetryIntervalSec");
\r
1305 dlg.ProxyServer = PackGetBool(p, "ProxyServer");
\r
1306 dlg.AdminMode = PackGetBool(p, "AdminMode");
\r
1307 dlg.ShowNoSavePassword = PackGetBool(p, "ShowNoSavePassword");
\r
1308 dlg.NoSavePassword = PackGetBool(p, "NoSavePassword");
\r
1309 dlg.CancelEvent = NewEvent();
\r
1312 t = NewThread(Win32CnPasswordDlgThreadProc, &dlg);
\r
1314 FreePack(RecvPack(s));
\r
1316 Set(dlg.CancelEvent);
\r
1318 WaitThread(t, INFINITE);
\r
1319 ReleaseEvent(dlg.CancelEvent);
\r
1323 // 接続エラーダイアログ用スレッド
\r
1324 void Win32CnConnectErrorDlgThreadProc(THREAD *thread, void *param)
\r
1326 UI_CONNECTERROR_DLG *dlg;
\r
1328 if (thread == NULL || param == NULL)
\r
1333 dlg = (UI_CONNECTERROR_DLG *)param;
\r
1335 if (ConnectErrorDlg(dlg))
\r
1337 PACK *p = NewPack();
\r
1339 PackAddBool(p, "ok", true);
\r
1340 PackAddBool(p, "HideWindow", dlg->HideWindow);
\r
1342 SendPack(dlg->Sock, p);
\r
1345 FreePack(RecvPack(dlg->Sock));
\r
1348 Disconnect(dlg->Sock);
\r
1351 // 接続エラーダイアログ (Win32)
\r
1352 void Win32CnConnectErrorDlg(SOCK *s, PACK *p)
\r
1354 UI_CONNECTERROR_DLG dlg;
\r
1356 Zero(&dlg, sizeof(dlg));
\r
1358 if (s == NULL || p == NULL)
\r
1363 PackGetUniStr(p, "AccountName", dlg.AccountName, sizeof(dlg.AccountName));
\r
1364 PackGetStr(p, "ServerName", dlg.ServerName, sizeof(dlg.ServerName));
\r
1365 dlg.Err = PackGetInt(p, "Err");
\r
1366 dlg.CurrentRetryCount = PackGetInt(p, "CurrentRetryCount");
\r
1367 dlg.RetryLimit = PackGetInt(p, "RetryLimit");
\r
1368 dlg.RetryIntervalSec = PackGetInt(p, "RetryIntervalSec");
\r
1369 dlg.HideWindow = PackGetBool(p, "HideWindow");
\r
1370 dlg.CancelEvent = NewEvent();
\r
1373 t = NewThread(Win32CnConnectErrorDlgThreadProc, &dlg);
\r
1375 FreePack(RecvPack(s));
\r
1377 Set(dlg.CancelEvent);
\r
1379 WaitThread(t, INFINITE);
\r
1380 ReleaseEvent(dlg.CancelEvent);
\r
1384 // ステータス表示器 (Win32)
\r
1385 void Win32CnStatusPrinter(SOCK *s, PACK *p)
\r
1388 wchar_t account_name[MAX_ACCOUNT_NAME_LEN + 1];
\r
1390 if (s == NULL || p == NULL)
\r
1395 PackGetUniStr(p, "account_name", account_name, sizeof(account_name));
\r
1397 w = StatusPrinterWindowStart(s, account_name);
\r
1401 PACK *p = RecvPack(s);
\r
1405 // 切断されたのでダイアログを終了する
\r
1410 wchar_t tmp[MAX_SIZE];
\r
1413 PackGetUniStr(p, "string", tmp, sizeof(tmp));
\r
1415 StatusPrinterWindowPrint(w, tmp);
\r
1421 StatusPrinterWindowStop(w);
\r
1424 // ドライバインストーラの起動 (Windows Vista 用)
\r
1425 void Win32CnExecDriverInstaller(SOCK *s, PACK *p)
\r
1427 char arg[MAX_SIZE];
\r
1429 void *helper = NULL;
\r
1431 if (s == NULL || p == NULL)
\r
1436 if (PackGetStr(p, "arg", arg, sizeof(arg)) == false)
\r
1443 helper = CmStartUacHelper();
\r
1446 ret = MsExecDriverInstaller(arg);
\r
1448 CmStopUacHelper(helper);
\r
1451 PackAddBool(p, "ret", ret);
\r
1457 #endif // OS_WIN32
\r
1460 void CnExecDriverInstaller(SOCK *s, PACK *p)
\r
1463 if (s == NULL || p == NULL)
\r
1469 Win32CnExecDriverInstaller(s, p);
\r
1470 #endif // OS_WIN32
\r
1474 void CnCheckCert(SOCK *s, PACK *p)
\r
1477 if (s == NULL || p == NULL)
\r
1483 Win32CnCheckCert(s, p);
\r
1484 #endif // OS_WIN32
\r
1488 void CnNicInfo(SOCK *s, PACK *p)
\r
1491 if (s == NULL || p == NULL)
\r
1497 Win32CnNicInfo(s, p);
\r
1498 #endif // OS_WIN32
\r
1502 void CnMsgDlg(SOCK *s, PACK *p)
\r
1505 if (s == NULL || p == NULL)
\r
1511 Win32CnMsgDlg(s, p);
\r
1512 #endif // OS_WIN32
\r
1516 void CnPasswordDlg(SOCK *s, PACK *p)
\r
1519 if (s == NULL || p == NULL)
\r
1525 Win32CnPasswordDlg(s, p);
\r
1526 #endif // OS_WIN32
\r
1530 void CnConnectErrorDlg(SOCK *s, PACK *p)
\r
1533 if (s == NULL || p == NULL)
\r
1539 Win32CnConnectErrorDlg(s, p);
\r
1540 #endif // OS_WIN32
\r
1544 void CnStatusPrinter(SOCK *s, PACK *p)
\r
1547 if (s == NULL || p == NULL)
\r
1553 Win32CnStatusPrinter(s, p);
\r
1554 #endif // OS_WIN32
\r
1557 // クライアント通知サービスリスナースレッド
\r
1558 // このあたりは急いで実装したのでコードがあまり美しくない。
\r
1559 void CnListenerProc(THREAD *thread, void *param)
\r
1561 TCP_ACCEPTED_PARAM *data = (TCP_ACCEPTED_PARAM *)param;
\r
1565 if (data == NULL || thread == NULL)
\r
1572 NoticeThreadInit(thread);
\r
1574 if (s->LocalIP.addr[0] == 127)
\r
1580 char function[MAX_SIZE];
\r
1582 if (PackGetStr(p, "function", function, sizeof(function)))
\r
1584 if (StrCmpi(function, "status_printer") == 0)
\r
1586 CnStatusPrinter(s, p);
\r
1588 else if (StrCmpi(function, "connecterror_dialog") == 0)
\r
1590 CnConnectErrorDlg(s, p);
\r
1592 else if (StrCmpi(function, "msg_dialog") == 0)
\r
1596 else if (StrCmpi(function, "nicinfo") == 0)
\r
1600 else if (StrCmpi(function, "password_dialog") == 0)
\r
1602 CnPasswordDlg(s, p);
\r
1604 else if (StrCmpi(function, "secure_sign") == 0)
\r
1606 CnSecureSign(s, p);
\r
1608 else if (StrCmpi(function, "check_cert") == 0)
\r
1610 CnCheckCert(s, p);
\r
1612 else if (StrCmpi(function, "exit") == 0)
\r
1615 MsTerminateProcess();
\r
1618 #endif // OS_WIN32
\r
1620 else if (StrCmpi(function, "get_session_id") == 0)
\r
1622 PACK *p = NewPack();
\r
1624 PackAddInt(p, "session_id", MsGetCurrentTerminalSessionId());
\r
1625 #endif // OS_WIN32
\r
1629 else if (StrCmpi(function, "exec_driver_installer") == 0)
\r
1631 CnExecDriverInstaller(s, p);
\r
1633 else if (StrCmpi(function, "release_socket") == 0)
\r
1636 CnReleaseSocket(s, p);
\r
1648 // Secure Sign を行う
\r
1649 void CnSecureSign(SOCK *s, PACK *p)
\r
1654 if (s == NULL || p == NULL)
\r
1659 Zero(&sign, sizeof(sign));
\r
1660 InRpcSecureSign(&sign, p);
\r
1663 // Win32: ダイアログを表示
\r
1664 ret = Win32CiSecureSign(&sign);
\r
1668 #endif // OS_WIN32
\r
1672 OutRpcSecureSign(p, &sign);
\r
1673 FreeRpcSecureSign(&sign);
\r
1675 PackAddBool(p, "ret", ret);
\r
1682 void CnReleaseSocket(SOCK *s, PACK *p)
\r
1685 UINT current_pid = 0;
\r
1687 if (s == NULL || p == NULL)
\r
1692 pid = PackGetInt(p, "pid");
\r
1695 current_pid = MsGetProcessId();
\r
1696 #endif // OS_WIN32
\r
1698 if (current_pid == pid)
\r
1703 Lock(cn_listener_lock);
\r
1705 if (cn_listener != NULL)
\r
1707 if (cn_listener->Halt == false)
\r
1709 StopListener(cn_listener);
\r
1711 cn_next_allow = Tick64() + (6 * 1000);
\r
1715 Unlock(cn_listener_lock);
\r
1718 // クライアント通知サービスの開始
\r
1723 UINT last_cursor_hash = 0;
\r
1724 bool last_session_active = false;
\r
1726 cn_next_allow = 0;
\r
1727 cn_listener_lock = NewLock();
\r
1730 MsSetShutdownParameters(0xff, 0x00000001);
\r
1731 InitWinUi(_UU("CN_TITLE"), _SS("DEFAULT_FONT"), _II("DEFAULT_FONT_SIZE"));
\r
1732 #endif // OS_WIN32
\r
1734 cedar = NewCedar(NULL, NULL);
\r
1736 if (CnCheckAlreadyExists(true))
\r
1739 ReleaseCedar(cedar);
\r
1742 #endif // OS_WIN32
\r
1747 MsRegWriteInt(REG_CURRENT_USER, CM_REG_KEY,
\r
1748 "NotifyServerProcessId", MsGetProcessId());
\r
1749 #endif // OS_WIN32
\r
1752 Lock(cn_listener_lock);
\r
1753 cn_listener = o = NewListenerEx(cedar, LISTENER_TCP, CLIENT_NOTIFY_PORT, CnListenerProc, NULL);
\r
1754 Unlock(cn_listener_lock);
\r
1758 UINT current_cursor_hash = 0;
\r
1759 bool cursor_changed = false;
\r
1763 current_cursor_hash = MsGetCursorPosHash();
\r
1764 #endif // OS_WIN32
\r
1766 if (last_cursor_hash != current_cursor_hash)
\r
1769 cursor_changed = true;
\r
1770 last_cursor_hash = current_cursor_hash;
\r
1773 Lock(cn_listener_lock);
\r
1775 // リスナーが開始した後一定間隔で状態をチェックする
\r
1776 if (cn_listener->Status == LISTENER_STATUS_TRYING || cn_listener->Halt)
\r
1778 bool session_active = false;
\r
1780 session_active = MsIsCurrentTerminalSessionActive();
\r
1781 if (cursor_changed)
\r
1783 // カーソル位置が変化してもターミナルセッションがアクティブでない
\r
1784 // 場合は変化していないものと見なす
\r
1785 if (session_active == false)
\r
1787 cursor_changed = false;
\r
1790 if (last_session_active != session_active)
\r
1792 // カーソルが変化していなくてもターミナルセッション
\r
1793 // 前回と比較してアクティブになった場合はカーソルが変化した
\r
1795 last_session_active = session_active;
\r
1797 if (session_active)
\r
1799 cursor_changed = true;
\r
1802 #endif // OS_WIN32
\r
1805 if (cn_next_allow <= Tick64())
\r
1807 if (cursor_changed || cn_listener->Halt)
\r
1809 if (cursor_changed)
\r
1811 // マウスカーソルが移動しているので自分がポートを開く権利を持っている
\r
1813 // そこで、他のプロセスが持っているポートを強制的に奪う。
\r
1814 CncReleaseSocket();
\r
1817 if (cn_listener->Halt)
\r
1819 ReleaseListener(cn_listener);
\r
1820 cn_listener = NULL;
\r
1822 Unlock(cn_listener_lock);
\r
1823 goto BEGIN_LISTENER;
\r
1829 Unlock(cn_listener_lock);
\r
1831 SleepThread(1000);
\r
1835 // バッファからアカウント情報を読み込む
\r
1836 RPC_CLIENT_CREATE_ACCOUNT *CiCfgToAccount(BUF *b)
\r
1838 RPC_CLIENT_CREATE_ACCOUNT *t;
\r
1847 f = CfgBufTextToFolder(b);
\r
1853 a = CiLoadClientAccount(f);
\r
1855 CfgDeleteFolder(f);
\r
1862 DeleteLock(a->lock);
\r
1864 t = ZeroMalloc(sizeof(RPC_CLIENT_CREATE_ACCOUNT));
\r
1865 t->ClientOption = a->ClientOption;
\r
1866 t->ClientAuth = a->ClientAuth;
\r
1867 t->StartupAccount = a->StartupAccount;
\r
1868 t->CheckServerCert = a->CheckServerCert;
\r
1869 t->ServerCert = a->ServerCert;
\r
1875 // アカウント情報をバッファに書き出す
\r
1876 BUF *CiAccountToCfg(RPC_CLIENT_CREATE_ACCOUNT *t)
\r
1887 root = CfgCreateFolder(NULL, TAG_ROOT);
\r
1888 Zero(&a, sizeof(a));
\r
1889 a.ClientOption = t->ClientOption;
\r
1890 a.ClientAuth = t->ClientAuth;
\r
1891 a.CheckServerCert = t->CheckServerCert;
\r
1892 a.ServerCert = t->ServerCert;
\r
1893 a.StartupAccount = t->StartupAccount;
\r
1895 CiWriteAccountData(root, &a);
\r
1897 b = CfgFolderToBufEx(root, true, true);
\r
1898 CfgDeleteFolder(root);
\r
1904 PACK *CiRpcDispatch(RPC *rpc, char *name, PACK *p)
\r
1906 CLIENT *c = rpc->Param;
\r
1909 if (rpc == NULL || name == NULL || p == NULL)
\r
1916 if (StrCmpi(name, "GetClientVersion") == 0)
\r
1918 RPC_CLIENT_VERSION a;
\r
1919 if (CtGetClientVersion(c, &a) == false)
\r
1921 RpcError(ret, c->Err);
\r
1925 OutRpcClientVersion(ret, &a);
\r
1928 else if (StrCmpi(name, "GetCmSetting") == 0)
\r
1931 if (CtGetCmSetting(c, &a) == false)
\r
1933 RpcError(ret, c->Err);
\r
1937 OutRpcCmSetting(ret, &a);
\r
1940 else if (StrCmpi(name, "SetCmSetting") == 0)
\r
1943 Zero(&a, sizeof(a));
\r
1944 InRpcCmSetting(&a, p);
\r
1945 if (CtSetCmSetting(c, &a) == false)
\r
1947 RpcError(ret, c->Err);
\r
1950 else if (StrCmpi(name, "SetPassword") == 0)
\r
1952 RPC_CLIENT_PASSWORD a;
\r
1953 InRpcClientPassword(&a, p);
\r
1954 if (CtSetPassword(c, &a) == false)
\r
1956 RpcError(ret, c->Err);
\r
1959 else if (StrCmpi(name, "GetPasswordSetting") == 0)
\r
1961 RPC_CLIENT_PASSWORD_SETTING a;
\r
1962 if (CtGetPasswordSetting(c, &a) == false)
\r
1964 RpcError(ret, c->Err);
\r
1968 OutRpcClientPasswordSetting(ret, &a);
\r
1971 else if (StrCmpi(name, "EnumCa") == 0)
\r
1973 RPC_CLIENT_ENUM_CA a;
\r
1974 if (CtEnumCa(c, &a) == false)
\r
1976 RpcError(ret, c->Err);
\r
1980 OutRpcClientEnumCa(ret, &a);
\r
1981 CiFreeClientEnumCa(&a);
\r
1984 else if (StrCmpi(name, "AddCa") == 0)
\r
1988 if (CtAddCa(c, &a) == false)
\r
1990 RpcError(ret, c->Err);
\r
1994 else if (StrCmpi(name, "DeleteCa") == 0)
\r
1996 RPC_CLIENT_DELETE_CA a;
\r
1997 InRpcClientDeleteCa(&a, p);
\r
1998 if (CtDeleteCa(c, &a) == false)
\r
2000 RpcError(ret, c->Err);
\r
2003 else if (StrCmpi(name, "GetCa") == 0)
\r
2006 InRpcGetCa(&a, p);
\r
2007 if (CtGetCa(c, &a) == false)
\r
2009 RpcError(ret, c->Err);
\r
2013 OutRpcGetCa(ret, &a);
\r
2017 else if (StrCmpi(name, "EnumSecure") == 0)
\r
2019 RPC_CLIENT_ENUM_SECURE a;
\r
2020 if (CtEnumSecure(c, &a) == false)
\r
2022 RpcError(ret, c->Err);
\r
2026 OutRpcClientEnumSecure(ret, &a);
\r
2027 CiFreeClientEnumSecure(&a);
\r
2030 else if (StrCmpi(name, "UseSecure") == 0)
\r
2033 InRpcUseSecure(&a, p);
\r
2034 if (CtUseSecure(c, &a) == false)
\r
2036 RpcError(ret, c->Err);
\r
2039 else if (StrCmpi(name, "GetUseSecure") == 0)
\r
2042 Zero(&a, sizeof(a));
\r
2043 if (CtGetUseSecure(c, &a) == false)
\r
2045 RpcError(ret, c->Err);
\r
2049 OutRpcUseSecure(ret, &a);
\r
2052 else if (StrCmpi(name, "EnumObjectInSecure") == 0)
\r
2054 RPC_ENUM_OBJECT_IN_SECURE a;
\r
2055 if (CtEnumObjectInSecure(c, &a) == false)
\r
2057 RpcError(ret, c->Err);
\r
2061 OutRpcEnumObjectInSecure(ret, &a);
\r
2062 CiFreeEnumObjectInSecure(&a);
\r
2065 else if (StrCmpi(name, "CreateVLan") == 0)
\r
2067 RPC_CLIENT_CREATE_VLAN a;
\r
2068 InRpcCreateVLan(&a, p);
\r
2069 if (CtCreateVLan(c, &a) == false)
\r
2071 RpcError(ret, c->Err);
\r
2074 else if (StrCmpi(name, "UpgradeVLan") == 0)
\r
2076 RPC_CLIENT_CREATE_VLAN a;
\r
2077 InRpcCreateVLan(&a, p);
\r
2078 if (CtUpgradeVLan(c, &a) == false)
\r
2080 RpcError(ret, c->Err);
\r
2083 else if (StrCmpi(name, "GetVLan") == 0)
\r
2085 RPC_CLIENT_GET_VLAN a;
\r
2086 InRpcClientGetVLan(&a, p);
\r
2087 if (CtGetVLan(c, &a) == false)
\r
2089 RpcError(ret, c->Err);
\r
2093 OutRpcClientGetVLan(ret, &a);
\r
2096 else if (StrCmpi(name, "SetVLan") == 0)
\r
2098 RPC_CLIENT_SET_VLAN a;
\r
2099 InRpcClientSetVLan(&a, p);
\r
2100 if (CtSetVLan(c, &a) == false)
\r
2102 RpcError(ret, c->Err);
\r
2105 else if (StrCmpi(name, "EnumVLan") == 0)
\r
2107 RPC_CLIENT_ENUM_VLAN a;
\r
2108 if (CtEnumVLan(c, &a) == false)
\r
2110 RpcError(ret, c->Err);
\r
2114 OutRpcClientEnumVLan(ret, &a);
\r
2115 CiFreeClientEnumVLan(&a);
\r
2118 else if (StrCmpi(name, "DeleteVLan") == 0)
\r
2120 RPC_CLIENT_CREATE_VLAN a;
\r
2121 InRpcCreateVLan(&a, p);
\r
2122 if (CtDeleteVLan(c, &a) == false)
\r
2124 RpcError(ret, c->Err);
\r
2127 else if (StrCmpi(name, "EnableVLan") == 0)
\r
2129 RPC_CLIENT_CREATE_VLAN a;
\r
2130 InRpcCreateVLan(&a, p);
\r
2131 if (CtEnableVLan(c, &a) == false)
\r
2133 RpcError(ret, c->Err);
\r
2136 else if (StrCmpi(name, "DisableVLan") == 0)
\r
2138 RPC_CLIENT_CREATE_VLAN a;
\r
2139 InRpcCreateVLan(&a, p);
\r
2140 if (CtDisableVLan(c, &a) == false)
\r
2142 RpcError(ret, c->Err);
\r
2145 else if (StrCmpi(name, "CreateAccount") == 0)
\r
2147 RPC_CLIENT_CREATE_ACCOUNT a;
\r
2148 InRpcClientCreateAccount(&a, p);
\r
2149 if (CtCreateAccount(c, &a) == false)
\r
2151 RpcError(ret, c->Err);
\r
2153 CiFreeClientCreateAccount(&a);
\r
2155 else if (StrCmpi(name, "EnumAccount") == 0)
\r
2157 RPC_CLIENT_ENUM_ACCOUNT a;
\r
2158 if (CtEnumAccount(c, &a) == false)
\r
2160 RpcError(ret, c->Err);
\r
2164 OutRpcClientEnumAccount(ret, &a);
\r
2165 CiFreeClientEnumAccount(&a);
\r
2168 else if (StrCmpi(name, "DeleteAccount") == 0)
\r
2170 RPC_CLIENT_DELETE_ACCOUNT a;
\r
2171 InRpcClientDeleteAccount(&a, p);
\r
2172 if (CtDeleteAccount(c, &a) == false)
\r
2174 RpcError(ret, c->Err);
\r
2177 else if (StrCmpi(name, "SetStartupAccount") == 0)
\r
2179 RPC_CLIENT_DELETE_ACCOUNT a;
\r
2180 InRpcClientDeleteAccount(&a, p);
\r
2181 if (CtSetStartupAccount(c, &a) == false)
\r
2183 RpcError(ret, c->Err);
\r
2186 else if (StrCmpi(name, "RemoveStartupAccount") == 0)
\r
2188 RPC_CLIENT_DELETE_ACCOUNT a;
\r
2189 InRpcClientDeleteAccount(&a, p);
\r
2190 if (CtRemoveStartupAccount(c, &a) == false)
\r
2192 RpcError(ret, c->Err);
\r
2195 else if (StrCmpi(name, "GetIssuer") == 0)
\r
2198 InRpcGetIssuer(&a, p);
\r
2199 if (CtGetIssuer(c, &a))
\r
2201 OutRpcGetIssuer(ret, &a);
\r
2205 RpcError(ret, c->Err);
\r
2207 CiFreeGetIssuer(&a);
\r
2209 else if (StrCmpi(name, "SetAccount") == 0)
\r
2211 RPC_CLIENT_CREATE_ACCOUNT a;
\r
2212 InRpcClientCreateAccount(&a, p);
\r
2213 if (CtSetAccount(c, &a) == false)
\r
2215 RpcError(ret, c->Err);
\r
2217 CiFreeClientCreateAccount(&a);
\r
2219 else if (StrCmpi(name, "GetAccount") == 0)
\r
2221 RPC_CLIENT_GET_ACCOUNT a;
\r
2222 InRpcClientGetAccount(&a, p);
\r
2223 if (CtGetAccount(c, &a) == false)
\r
2225 RpcError(ret, c->Err);
\r
2229 OutRpcClientGetAccount(ret, &a);
\r
2231 CiFreeClientGetAccount(&a);
\r
2233 else if (StrCmpi(name, "RenameAccount") == 0)
\r
2235 RPC_RENAME_ACCOUNT a;
\r
2236 InRpcRenameAccount(&a, p);
\r
2237 if (CtRenameAccount(c, &a) == false)
\r
2239 RpcError(ret, c->Err);
\r
2242 else if (StrCmpi(name, "SetClientConfig") == 0)
\r
2245 InRpcClientConfig(&a, p);
\r
2246 if (CtSetClientConfig(c, &a) == false)
\r
2248 RpcError(ret, c->Err);
\r
2251 else if (StrCmpi(name, "GetClientConfig") == 0)
\r
2254 if (CtGetClientConfig(c, &a) == false)
\r
2256 RpcError(ret, c->Err);
\r
2260 OutRpcClientConfig(ret, &a);
\r
2263 else if (StrCmpi(name, "Connect") == 0)
\r
2265 RPC_CLIENT_CONNECT a;
\r
2266 InRpcClientConnect(&a, p);
\r
2267 if (CtConnect(c, &a) == false)
\r
2269 RpcError(ret, c->Err);
\r
2272 else if (StrCmpi(name, "Disconnect") == 0)
\r
2274 RPC_CLIENT_CONNECT a;
\r
2275 InRpcClientConnect(&a, p);
\r
2276 if (CtDisconnect(c, &a) == false)
\r
2278 RpcError(ret, c->Err);
\r
2281 else if (StrCmpi(name, "GetAccountStatus") == 0)
\r
2283 RPC_CLIENT_GET_CONNECTION_STATUS a;
\r
2284 InRpcClientGetConnectionStatus(&a, p);
\r
2285 if (CtGetAccountStatus(c, &a) == false)
\r
2287 RpcError(ret, c->Err);
\r
2291 OutRpcClientGetConnectionStatus(ret, &a);
\r
2293 CiFreeClientGetConnectionStatus(&a);
\r
2305 UINT CcSetCmSetting(REMOTE_CLIENT *r, CM_SETTING *a)
\r
2310 if (r == NULL || a == NULL)
\r
2312 return ERR_INTERNAL_ERROR;
\r
2316 OutRpcCmSetting(p, a);
\r
2318 ret = RpcCall(r->Rpc, "SetCmSetting", p);
\r
2327 err = RpcGetError(ret);
\r
2334 UINT CcGetCmSetting(REMOTE_CLIENT *r, CM_SETTING *a)
\r
2338 if (r == NULL || a == NULL)
\r
2340 return ERR_INTERNAL_ERROR;
\r
2343 ret = RpcCall(r->Rpc, "GetCmSetting", NULL);
\r
2347 InRpcCmSetting(a, ret);
\r
2353 UINT err = RpcGetError(ret);
\r
2360 UINT CcGetClientVersion(REMOTE_CLIENT *r, RPC_CLIENT_VERSION *a)
\r
2364 if (r == NULL || a == NULL)
\r
2366 return ERR_INTERNAL_ERROR;
\r
2369 ret = RpcCall(r->Rpc, "GetClientVersion", NULL);
\r
2373 InRpcClientVersion(a, ret);
\r
2379 UINT err = RpcGetError(ret);
\r
2386 UINT CcSetPassword(REMOTE_CLIENT *r, RPC_CLIENT_PASSWORD *pass)
\r
2390 if (r == NULL || pass == NULL)
\r
2392 return ERR_INTERNAL_ERROR;
\r
2397 OutRpcClientPassword(p, pass);
\r
2399 ret = RpcCall(r->Rpc, "SetPassword", p);
\r
2408 UINT err = RpcGetError(ret);
\r
2415 UINT CcGetPasswordSetting(REMOTE_CLIENT *r, RPC_CLIENT_PASSWORD_SETTING *a)
\r
2420 if (r == NULL || a == NULL)
\r
2422 return ERR_INTERNAL_ERROR;
\r
2425 ret = RpcCall(r->Rpc, "GetPasswordSetting", NULL);
\r
2429 InRpcClientPasswordSetting(a, ret);
\r
2433 err = RpcGetError(ret);
\r
2441 UINT CcEnumCa(REMOTE_CLIENT *r, RPC_CLIENT_ENUM_CA *e)
\r
2446 if (r == NULL || e == NULL)
\r
2448 return ERR_INTERNAL_ERROR;
\r
2451 ret = RpcCall(r->Rpc, "EnumCa", NULL);
\r
2455 InRpcClientEnumCa(e, ret);
\r
2459 err = RpcGetError(ret);
\r
2468 UINT CcAddCa(REMOTE_CLIENT *r, RPC_CERT *cert)
\r
2473 if (r == NULL || cert == NULL)
\r
2475 return ERR_INTERNAL_ERROR;
\r
2479 OutRpcCert(p, cert);
\r
2481 ret = RpcCall(r->Rpc, "AddCa", p);
\r
2483 if (RpcIsOk(ret) == false)
\r
2485 err = RpcGetError(ret);
\r
2494 UINT CcDeleteCa(REMOTE_CLIENT *r, RPC_CLIENT_DELETE_CA *c)
\r
2499 if (r == NULL || c == NULL)
\r
2501 return ERR_INTERNAL_ERROR;
\r
2505 OutRpcClientDeleteCa(p, c);
\r
2507 ret = RpcCall(r->Rpc, "DeleteCa", p);
\r
2509 if (RpcIsOk(ret) == false)
\r
2511 err = RpcGetError(ret);
\r
2520 UINT CcGetIssuer(REMOTE_CLIENT *r, RPC_GET_ISSUER *a)
\r
2525 if (r == NULL || a == NULL)
\r
2527 return ERR_INTERNAL_ERROR;
\r
2531 OutRpcGetIssuer(p, a);
\r
2533 ret = RpcCall(r->Rpc, "GetIssuer", p);
\r
2542 InRpcGetIssuer(a, ret);
\r
2546 err = RpcGetError(ret);
\r
2555 UINT CcGetCa(REMOTE_CLIENT *r, RPC_GET_CA *get)
\r
2560 if (r == NULL || get == NULL)
\r
2562 return ERR_INTERNAL_ERROR;
\r
2566 OutRpcGetCa(p, get);
\r
2568 ret = RpcCall(r->Rpc, "GetCa", p);
\r
2572 InRpcGetCa(get, ret);
\r
2576 err = RpcGetError(ret);
\r
2585 UINT CcEnumSecure(REMOTE_CLIENT *r, RPC_CLIENT_ENUM_SECURE *e)
\r
2590 if (r == NULL || e == NULL)
\r
2592 return ERR_INTERNAL_ERROR;
\r
2595 ret = RpcCall(r->Rpc, "EnumSecure", NULL);
\r
2599 InRpcClientEnumSecure(e, ret);
\r
2603 err = RpcGetError(ret);
\r
2611 // 使用しているセキュアデバイスの取得
\r
2612 UINT CcGetUseSecure(REMOTE_CLIENT *r, RPC_USE_SECURE *sec)
\r
2617 if (r == NULL || sec == NULL)
\r
2619 return ERR_INTERNAL_ERROR;
\r
2624 ret = RpcCall(r->Rpc, "GetUseSecure", p);
\r
2626 if (RpcIsOk(ret) == false)
\r
2628 err = RpcGetError(ret);
\r
2632 InRpcUseSecure(sec, ret);
\r
2641 UINT CcUseSecure(REMOTE_CLIENT *r, RPC_USE_SECURE *sec)
\r
2646 if (r == NULL || sec == NULL)
\r
2648 return ERR_INTERNAL_ERROR;
\r
2652 OutRpcUseSecure(p, sec);
\r
2654 ret = RpcCall(r->Rpc, "UseSecure", p);
\r
2656 if (RpcIsOk(ret) == false)
\r
2658 err = RpcGetError(ret);
\r
2666 // セキュアデバイス内のオブジェクトの列挙
\r
2667 UINT CcEnumObjectInSecure(REMOTE_CLIENT *r, RPC_ENUM_OBJECT_IN_SECURE *e)
\r
2672 if (r == NULL || e == NULL)
\r
2674 return ERR_INTERNAL_ERROR;
\r
2677 ret = RpcCall(r->Rpc, "EnumObjectInSecure", NULL);
\r
2681 InRpcEnumObjectInSecure(e, ret);
\r
2685 err = RpcGetError(ret);
\r
2694 UINT CcCreateVLan(REMOTE_CLIENT *r, RPC_CLIENT_CREATE_VLAN *create)
\r
2700 if (r == NULL || create == NULL)
\r
2702 return ERR_INTERNAL_ERROR;
\r
2706 OutRpcCreateVLan(p, create);
\r
2709 s = MsNoWarningSoundInit();
\r
2710 #endif // OS_WIN32
\r
2712 ret = RpcCall(r->Rpc, "CreateVLan", p);
\r
2715 MsNoWarningSoundFree(s);
\r
2716 #endif // OS_WIN32
\r
2718 if (RpcIsOk(ret) == false)
\r
2720 err = RpcGetError(ret);
\r
2729 UINT CcUpgradeVLan(REMOTE_CLIENT *r, RPC_CLIENT_CREATE_VLAN *create)
\r
2735 if (r == NULL || create == NULL)
\r
2737 return ERR_INTERNAL_ERROR;
\r
2741 OutRpcCreateVLan(p, create);
\r
2744 s = MsNoWarningSoundInit();
\r
2745 #endif // OS_WIN32
\r
2747 ret = RpcCall(r->Rpc, "UpgradeVLan", p);
\r
2750 MsNoWarningSoundFree(s);
\r
2751 #endif // OS_WIN32
\r
2754 if (RpcIsOk(ret) == false)
\r
2756 err = RpcGetError(ret);
\r
2765 UINT CcGetVLan(REMOTE_CLIENT *r, RPC_CLIENT_GET_VLAN *get)
\r
2770 if (r == NULL || get == NULL)
\r
2772 return ERR_INTERNAL_ERROR;
\r
2776 OutRpcClientGetVLan(p, get);
\r
2778 ret = RpcCall(r->Rpc, "GetVLan", p);
\r
2782 InRpcClientGetVLan(get, ret);
\r
2786 err = RpcGetError(ret);
\r
2795 UINT CcSetVLan(REMOTE_CLIENT *r, RPC_CLIENT_SET_VLAN *set)
\r
2800 if (r == NULL || set == NULL)
\r
2802 return ERR_INTERNAL_ERROR;
\r
2806 OutRpcClientSetVLan(p, set);
\r
2808 ret = RpcCall(r->Rpc, "SetVLan", p);
\r
2810 if (RpcIsOk(ret) == false)
\r
2812 err = RpcGetError(ret);
\r
2821 UINT CcEnumVLan(REMOTE_CLIENT *r, RPC_CLIENT_ENUM_VLAN *e)
\r
2826 if (r == NULL || e == NULL)
\r
2828 return ERR_INTERNAL_ERROR;
\r
2831 ret = RpcCall(r->Rpc, "EnumVLan", NULL);
\r
2835 InRpcClientEnumVLan(e, ret);
\r
2839 err = RpcGetError(ret);
\r
2848 UINT CcDeleteVLan(REMOTE_CLIENT *r, RPC_CLIENT_CREATE_VLAN *d)
\r
2853 if (r == NULL || d == NULL)
\r
2855 return ERR_INTERNAL_ERROR;
\r
2859 OutRpcCreateVLan(p, d);
\r
2861 ret = RpcCall(r->Rpc, "DeleteVLan", p);
\r
2863 if (RpcIsOk(ret) == false)
\r
2865 err = RpcGetError(ret);
\r
2874 UINT CcEnableVLan(REMOTE_CLIENT *r, RPC_CLIENT_CREATE_VLAN *vlan)
\r
2879 if (r == NULL || vlan == NULL)
\r
2881 return ERR_INTERNAL_ERROR;
\r
2885 OutRpcCreateVLan(p, vlan);
\r
2887 ret = RpcCall(r->Rpc, "EnableVLan", p);
\r
2889 if (RpcIsOk(ret) == false)
\r
2891 err = RpcGetError(ret);
\r
2900 UINT CcDisableVLan(REMOTE_CLIENT *r, RPC_CLIENT_CREATE_VLAN *vlan)
\r
2905 if (r == NULL || vlan == NULL)
\r
2907 return ERR_INTERNAL_ERROR;
\r
2911 OutRpcCreateVLan(p, vlan);
\r
2913 ret = RpcCall(r->Rpc, "DisableVLan", p);
\r
2915 if (RpcIsOk(ret) == false)
\r
2917 err = RpcGetError(ret);
\r
2926 UINT CcCreateAccount(REMOTE_CLIENT *r, RPC_CLIENT_CREATE_ACCOUNT *a)
\r
2931 if (r == NULL || a == NULL)
\r
2933 return ERR_INTERNAL_ERROR;
\r
2937 OutRpcClientCreateAccount(p, a);
\r
2939 ret = RpcCall(r->Rpc, "CreateAccount", p);
\r
2941 if (RpcIsOk(ret) == false)
\r
2943 err = RpcGetError(ret);
\r
2952 UINT CcEnumAccount(REMOTE_CLIENT *r, RPC_CLIENT_ENUM_ACCOUNT *e)
\r
2957 if (r == NULL || e == NULL)
\r
2959 return ERR_INTERNAL_ERROR;
\r
2962 ret = RpcCall(r->Rpc, "EnumAccount", NULL);
\r
2967 InRpcClientEnumAccount(e, ret);
\r
2969 for (i = 0;i < e->NumItem;i++)
\r
2971 RPC_CLIENT_ENUM_ACCOUNT_ITEM *t = e->Items[i];
\r
2973 if (IsEmptyStr(t->HubName) && t->Port == 0)
\r
2976 RPC_CLIENT_GET_ACCOUNT a;
\r
2978 // 古いバージョンの VPN Client では列挙時に HUB 名とポート番号
\r
2979 // を取得できないので、別途取得する。
\r
2980 Zero(&a, sizeof(a));
\r
2981 UniStrCpy(a.AccountName, sizeof(a.AccountName), t->AccountName);
\r
2982 err2 = CcGetAccount(r, &a);
\r
2983 if (err2 == ERR_NO_ERROR)
\r
2985 StrCpy(t->HubName, sizeof(t->HubName), a.ClientOption->HubName);
\r
2986 t->Port = a.ClientOption->Port;
\r
2988 CiFreeClientGetAccount(&a);
\r
2995 err = RpcGetError(ret);
\r
3004 UINT CcRemoveStartupAccount(REMOTE_CLIENT *r, RPC_CLIENT_DELETE_ACCOUNT *a)
\r
3009 if (r == NULL || a == NULL)
\r
3011 return ERR_INTERNAL_ERROR;
\r
3015 OutRpcClientDeleteAccount(p, a);
\r
3017 ret = RpcCall(r->Rpc, "RemoveStartupAccount", p);
\r
3019 if (RpcIsOk(ret) == false)
\r
3021 err = RpcGetError(ret);
\r
3030 UINT CcSetStartupAccount(REMOTE_CLIENT *r, RPC_CLIENT_DELETE_ACCOUNT *a)
\r
3035 if (r == NULL || a == NULL)
\r
3037 return ERR_INTERNAL_ERROR;
\r
3041 OutRpcClientDeleteAccount(p, a);
\r
3043 ret = RpcCall(r->Rpc, "SetStartupAccount", p);
\r
3045 if (RpcIsOk(ret) == false)
\r
3047 err = RpcGetError(ret);
\r
3056 UINT CcDeleteAccount(REMOTE_CLIENT *r, RPC_CLIENT_DELETE_ACCOUNT *a)
\r
3061 if (r == NULL || a == NULL)
\r
3063 return ERR_INTERNAL_ERROR;
\r
3067 OutRpcClientDeleteAccount(p, a);
\r
3069 ret = RpcCall(r->Rpc, "DeleteAccount", p);
\r
3071 if (RpcIsOk(ret) == false)
\r
3073 err = RpcGetError(ret);
\r
3082 UINT CcSetAccount(REMOTE_CLIENT *r, RPC_CLIENT_CREATE_ACCOUNT *a)
\r
3087 if (r == NULL || a == NULL)
\r
3089 return ERR_INTERNAL_ERROR;
\r
3093 OutRpcClientCreateAccount(p, a);
\r
3095 ret = RpcCall(r->Rpc, "SetAccount", p);
\r
3097 if (RpcIsOk(ret) == false)
\r
3099 err = RpcGetError(ret);
\r
3108 UINT CcGetAccount(REMOTE_CLIENT *r, RPC_CLIENT_GET_ACCOUNT *a)
\r
3113 if (r == NULL || a == NULL)
\r
3115 return ERR_INTERNAL_ERROR;
\r
3119 OutRpcClientGetAccount(p, a);
\r
3121 ret = RpcCall(r->Rpc, "GetAccount", p);
\r
3125 InRpcClientGetAccount(a, ret);
\r
3129 err = RpcGetError(ret);
\r
3138 UINT CcRenameAccount(REMOTE_CLIENT *r, RPC_RENAME_ACCOUNT *rename)
\r
3143 if (r == NULL || rename == NULL)
\r
3145 return ERR_INTERNAL_ERROR;
\r
3149 OutRpcRenameAccount(p, rename);
\r
3151 ret = RpcCall(r->Rpc, "RenameAccount", p);
\r
3153 if (RpcIsOk(ret) == false)
\r
3155 err = RpcGetError(ret);
\r
3164 UINT CcSetClientConfig(REMOTE_CLIENT *r, CLIENT_CONFIG *o)
\r
3169 if (r == NULL || o == NULL)
\r
3171 return ERR_INTERNAL_ERROR;
\r
3175 OutRpcClientConfig(p, o);
\r
3177 ret = RpcCall(r->Rpc, "SetClientConfig", p);
\r
3179 if (RpcIsOk(ret) == false)
\r
3181 err = RpcGetError(ret);
\r
3190 UINT CcGetClientConfig(REMOTE_CLIENT *r, CLIENT_CONFIG *o)
\r
3195 if (r == NULL || o == NULL)
\r
3197 return ERR_INTERNAL_ERROR;
\r
3200 ret = RpcCall(r->Rpc, "GetClientConfig", NULL);
\r
3204 InRpcClientConfig(o, ret);
\r
3208 err = RpcGetError(ret);
\r
3216 // サービスをフォアグラウンドプロセスに設定する
\r
3217 void CcSetServiceToForegroundProcess(REMOTE_CLIENT *r)
\r
3226 if (r->Rpc != NULL && r->Rpc->Sock != NULL && r->Rpc->Sock->RemoteIP.addr[0] == 127)
\r
3228 if (OS_IS_WINDOWS_NT(GetOsInfo()->OsType) &&
\r
3229 GET_KETA(GetOsInfo()->OsType, 100) >= 2)
\r
3231 // Windows 2000 以降でのみこの操作は行う
\r
3232 RPC_CLIENT_VERSION v;
\r
3233 Zero(&v, sizeof(v));
\r
3235 if (r->ClientBuildInt == 0)
\r
3237 CcGetClientVersion(r, &v);
\r
3238 r->ClientBuildInt = v.ClientBuildInt;
\r
3239 r->ProcessId = v.ProcessId;
\r
3241 if (r->ProcessId != 0 && r->ClientBuildInt <= 5080)
\r
3244 // サービスプロセスをフォアグラウンドウインドウに設定する
\r
3245 AllowFGWindow(v.ProcessId);
\r
3246 #endif // OS_WIN32
\r
3253 UINT CcConnect(REMOTE_CLIENT *r, RPC_CLIENT_CONNECT *connect)
\r
3258 if (r == NULL || connect == NULL)
\r
3260 return ERR_INTERNAL_ERROR;
\r
3263 CcSetServiceToForegroundProcess(r);
\r
3266 OutRpcClientConnect(p, connect);
\r
3268 ret = RpcCall(r->Rpc, "Connect", p);
\r
3270 if (RpcIsOk(ret) == false)
\r
3272 err = RpcGetError(ret);
\r
3281 UINT CcDisconnect(REMOTE_CLIENT *r, RPC_CLIENT_CONNECT *connect)
\r
3286 if (r == NULL || connect == NULL)
\r
3288 return ERR_INTERNAL_ERROR;
\r
3291 CcSetServiceToForegroundProcess(r);
\r
3294 OutRpcClientConnect(p, connect);
\r
3296 ret = RpcCall(r->Rpc, "Disconnect", p);
\r
3298 if (RpcIsOk(ret) == false)
\r
3300 err = RpcGetError(ret);
\r
3309 UINT CcGetAccountStatus(REMOTE_CLIENT *r, RPC_CLIENT_GET_CONNECTION_STATUS *st)
\r
3314 if (r == NULL || st == NULL)
\r
3316 return ERR_INTERNAL_ERROR;
\r
3320 OutRpcClientGetConnectionStatus(p, st);
\r
3322 ret = RpcCall(r->Rpc, "GetAccountStatus", p);
\r
3326 InRpcClientGetConnectionStatus(st, ret);
\r
3330 err = RpcGetError(ret);
\r
3339 // クライアントサービスが接続マネージャに対して通知を送信する
\r
3340 void CiNotify(CLIENT *c)
\r
3348 // すべての通知イベントを起動する
\r
3349 LockList(c->NotifyCancelList);
\r
3352 for (i = 0;i < LIST_NUM(c->NotifyCancelList);i++)
\r
3354 CANCEL *cancel = LIST_DATA(c->NotifyCancelList, i);
\r
3358 UnlockList(c->NotifyCancelList);
\r
3361 // RPC_CLIENT_ENUM_ACCOUNT の解放
\r
3362 void CiFreeClientEnumAccount(RPC_CLIENT_ENUM_ACCOUNT *a)
\r
3371 for (i = 0;i < a->NumItem;i++)
\r
3373 RPC_CLIENT_ENUM_ACCOUNT_ITEM *e = a->Items[i];
\r
3380 // 一定時間ごとに設定ファイルを保存するスレッド
\r
3381 void CiSaverThread(THREAD *t, void *param)
\r
3383 CLIENT *c = (CLIENT *)param;
\r
3385 if (t == NULL || param == NULL)
\r
3390 NoticeThreadInit(t);
\r
3393 while (c->Halt == false)
\r
3395 Wait(c->SaverHalter, CLIENT_SAVER_INTERVAL);
\r
3398 CiSaveConfigurationFile(c);
\r
3403 void CiInitSaver(CLIENT *c)
\r
3411 c->SaverHalter = NewEvent();
\r
3413 c->SaverThread = NewThread(CiSaverThread, c);
\r
3414 WaitThreadInit(c->SaverThread);
\r
3418 void CiFreeSaver(CLIENT *c)
\r
3427 Set(c->SaverHalter);
\r
3428 WaitThread(c->SaverThread, INFINITE);
\r
3429 ReleaseThread(c->SaverThread);
\r
3431 ReleaseEvent(c->SaverHalter);
\r
3435 void InRpcCmSetting(CM_SETTING *c, PACK *p)
\r
3438 if (c == NULL || p == NULL)
\r
3443 Zero(c, sizeof(CM_SETTING));
\r
3444 c->EasyMode = PackGetBool(p, "EasyMode");
\r
3445 c->LockMode = PackGetBool(p, "LockMode");
\r
3446 PackGetData2(p, "HashedPassword", c->HashedPassword, sizeof(c->HashedPassword));
\r
3448 void OutRpcCmSetting(PACK *p, CM_SETTING *c)
\r
3451 if (c == NULL || p == NULL)
\r
3456 PackAddBool(p, "EasyMode", c->EasyMode);
\r
3457 PackAddBool(p, "LockMode", c->LockMode);
\r
3458 PackAddData(p, "HashedPassword", c->HashedPassword, sizeof(c->HashedPassword));
\r
3462 void InRpcClientConfig(CLIENT_CONFIG *c, PACK *p)
\r
3465 if (c == NULL || p == NULL)
\r
3470 Zero(c, sizeof(CLIENT_CONFIG));
\r
3471 c->UseKeepConnect = PackGetInt(p, "UseKeepConnect") == 0 ? false : true;
\r
3472 c->KeepConnectPort = PackGetInt(p, "KeepConnectPort");
\r
3473 c->KeepConnectProtocol = PackGetInt(p, "KeepConnectProtocol");
\r
3474 c->KeepConnectInterval = PackGetInt(p, "KeepConnectInterval");
\r
3475 c->AllowRemoteConfig = PackGetInt(p, "AllowRemoteConfig") == 0 ? false : true;
\r
3476 PackGetStr(p, "KeepConnectHost", c->KeepConnectHost, sizeof(c->KeepConnectHost));
\r
3478 void OutRpcClientConfig(PACK *p, CLIENT_CONFIG *c)
\r
3481 if (c == NULL || p == NULL)
\r
3486 PackAddInt(p, "UseKeepConnect", c->UseKeepConnect);
\r
3487 PackAddInt(p, "KeepConnectPort", c->KeepConnectPort);
\r
3488 PackAddInt(p, "KeepConnectProtocol", c->KeepConnectProtocol);
\r
3489 PackAddInt(p, "KeepConnectInterval", c->KeepConnectInterval);
\r
3490 PackAddInt(p, "AllowRemoteConfig", c->AllowRemoteConfig);
\r
3491 PackAddStr(p, "KeepConnectHost", c->KeepConnectHost);
\r
3494 // RPC_CLIENT_VERSION
\r
3495 void InRpcClientVersion(RPC_CLIENT_VERSION *ver, PACK *p)
\r
3498 if (ver == NULL || p == NULL)
\r
3503 Zero(ver, sizeof(RPC_CLIENT_VERSION));
\r
3504 PackGetStr(p, "ClientProductName", ver->ClientProductName, sizeof(ver->ClientProductName));
\r
3505 PackGetStr(p, "ClientVersionString", ver->ClientVersionString, sizeof(ver->ClientVersionString));
\r
3506 PackGetStr(p, "ClientBuildInfoString", ver->ClientBuildInfoString, sizeof(ver->ClientBuildInfoString));
\r
3507 ver->ClientVerInt = PackGetInt(p, "ClientVerInt");
\r
3508 ver->ClientBuildInt = PackGetInt(p, "ClientBuildInt");
\r
3509 ver->ProcessId = PackGetInt(p, "ProcessId");
\r
3510 ver->OsType = PackGetInt(p, "OsType");
\r
3512 void OutRpcClientVersion(PACK *p, RPC_CLIENT_VERSION *ver)
\r
3515 if (ver == NULL || p == NULL)
\r
3520 PackAddStr(p, "ClientProductName", ver->ClientProductName);
\r
3521 PackAddStr(p, "ClientVersionString", ver->ClientVersionString);
\r
3522 PackAddStr(p, "ClientBuildInfoString", ver->ClientBuildInfoString);
\r
3523 PackAddInt(p, "ClientVerInt", ver->ClientVerInt);
\r
3524 PackAddInt(p, "ClientBuildInt", ver->ClientBuildInt);
\r
3525 PackAddInt(p, "ProcessId", ver->ProcessId);
\r
3526 PackAddInt(p, "OsType", ver->OsType);
\r
3529 // RPC_CLIENT_PASSWORD
\r
3530 void InRpcClientPassword(RPC_CLIENT_PASSWORD *pw, PACK *p)
\r
3533 if (pw == NULL || p == NULL)
\r
3538 Zero(pw, sizeof(RPC_CLIENT_PASSWORD));
\r
3539 PackGetStr(p, "Password", pw->Password, sizeof(pw->Password));
\r
3540 pw->PasswordRemoteOnly = PackGetInt(p, "PasswordRemoteOnly");
\r
3542 void OutRpcClientPassword(PACK *p, RPC_CLIENT_PASSWORD *pw)
\r
3545 if (pw == NULL || p == NULL)
\r
3550 PackAddStr(p, "Password", pw->Password);
\r
3551 PackAddInt(p, "PasswordRemoteOnly", pw->PasswordRemoteOnly);
\r
3554 // RPC_CLIENT_PASSWORD_SETTING
\r
3555 void InRpcClientPasswordSetting(RPC_CLIENT_PASSWORD_SETTING *a, PACK *p)
\r
3558 if (a == NULL || p == NULL)
\r
3563 Zero(a, sizeof(RPC_CLIENT_PASSWORD_SETTING));
\r
3565 a->IsPasswordPresented = PackGetInt(p, "IsPasswordPresented") == 0 ? false : true;
\r
3566 a->PasswordRemoteOnly = PackGetInt(p, "PasswordRemoteOnly") == 0 ? false : true;
\r
3568 void OutRpcClientPasswordSetting(PACK *p, RPC_CLIENT_PASSWORD_SETTING *a)
\r
3571 if (a == NULL || p == NULL)
\r
3576 PackAddInt(p, "IsPasswordPresented", a->IsPasswordPresented);
\r
3577 PackAddInt(p, "PasswordRemoteOnly", a->PasswordRemoteOnly);
\r
3580 // RPC_CLIENT_ENUM_CA
\r
3581 void InRpcClientEnumCa(RPC_CLIENT_ENUM_CA *e, PACK *p)
\r
3585 if (e == NULL || p == NULL)
\r
3590 Zero(e, sizeof(RPC_CLIENT_ENUM_CA));
\r
3591 e->NumItem = PackGetNum(p, "NumItem");
\r
3593 e->Items = ZeroMalloc(sizeof(RPC_CLIENT_ENUM_CA_ITEM *) * e->NumItem);
\r
3594 for (i = 0;i < e->NumItem;i++)
\r
3596 RPC_CLIENT_ENUM_CA_ITEM *item = ZeroMalloc(sizeof(RPC_CLIENT_ENUM_CA_ITEM));
\r
3597 e->Items[i] = item;
\r
3599 item->Key = PackGetIntEx(p, "Key", i);
\r
3600 PackGetUniStrEx(p, "SubjectName", item->SubjectName, sizeof(item->SubjectName), i);
\r
3601 PackGetUniStrEx(p, "IssuerName", item->IssuerName, sizeof(item->IssuerName), i);
\r
3602 item->Expires = PackGetInt64Ex(p, "Expires", i);
\r
3605 void OutRpcClientEnumCa(PACK *p, RPC_CLIENT_ENUM_CA *e)
\r
3609 if (e == NULL || p == NULL)
\r
3614 PackAddNum(p, "NumItem", e->NumItem);
\r
3616 for (i = 0;i < e->NumItem;i++)
\r
3618 RPC_CLIENT_ENUM_CA_ITEM *item = e->Items[i];
\r
3619 PackAddIntEx(p, "Key", item->Key, i, e->NumItem);
\r
3620 PackAddUniStrEx(p, "SubjectName", item->SubjectName, i, e->NumItem);
\r
3621 PackAddUniStrEx(p, "IssuerName", item->IssuerName, i, e->NumItem);
\r
3622 PackAddInt64Ex(p, "Expires", item->Expires, i, e->NumItem);
\r
3627 void InRpcGetIssuer(RPC_GET_ISSUER *c, PACK *p)
\r
3631 if (c == NULL || p == NULL)
\r
3636 Zero(c, sizeof(RPC_GET_ISSUER));
\r
3637 b = PackGetBuf(p, "x");
\r
3644 c->x = BufToX(b, false);
\r
3648 b = PackGetBuf(p, "issuer_x");
\r
3651 c->issuer_x = BufToX(b, false);
\r
3655 void OutRpcGetIssuer(PACK *p, RPC_GET_ISSUER *c)
\r
3659 if (p == NULL || c == NULL)
\r
3666 b = XToBuf(c->x, false);
\r
3668 PackAddBuf(p, "x", b);
\r
3672 if (c->issuer_x != NULL)
\r
3674 b = XToBuf(c->issuer_x, false);
\r
3676 PackAddBuf(p, "issuer_x", b);
\r
3682 void InRpcTrafficEx(TRAFFIC *t, PACK *p, UINT i)
\r
3685 if (t == NULL || p == NULL)
\r
3690 Zero(t, sizeof(TRAFFIC));
\r
3691 t->Recv.BroadcastBytes = PackGetInt64Ex(p, "Ex.Recv.BroadcastBytes", i);
\r
3692 t->Recv.BroadcastCount = PackGetInt64Ex(p, "Ex.Recv.BroadcastCount", i);
\r
3693 t->Recv.UnicastBytes = PackGetInt64Ex(p, "Ex.Recv.UnicastBytes", i);
\r
3694 t->Recv.UnicastCount = PackGetInt64Ex(p, "Ex.Recv.UnicastCount", i);
\r
3695 t->Send.BroadcastBytes = PackGetInt64Ex(p, "Ex.Send.BroadcastBytes", i);
\r
3696 t->Send.BroadcastCount = PackGetInt64Ex(p, "Ex.Send.BroadcastCount", i);
\r
3697 t->Send.UnicastBytes = PackGetInt64Ex(p, "Ex.Send.UnicastBytes", i);
\r
3698 t->Send.UnicastCount = PackGetInt64Ex(p, "Ex.Send.UnicastCount", i);
\r
3700 void OutRpcTrafficEx(TRAFFIC *t, PACK *p, UINT i, UINT num)
\r
3703 if (t == NULL || p == NULL)
\r
3708 PackAddInt64Ex(p, "Ex.Recv.BroadcastBytes", t->Recv.BroadcastBytes, i, num);
\r
3709 PackAddInt64Ex(p, "Ex.Recv.BroadcastCount", t->Recv.BroadcastCount, i, num);
\r
3710 PackAddInt64Ex(p, "Ex.Recv.UnicastBytes", t->Recv.UnicastBytes, i, num);
\r
3711 PackAddInt64Ex(p, "Ex.Recv.UnicastCount", t->Recv.UnicastCount, i, num);
\r
3712 PackAddInt64Ex(p, "Ex.Send.BroadcastBytes", t->Send.BroadcastBytes, i, num);
\r
3713 PackAddInt64Ex(p, "Ex.Send.BroadcastCount", t->Send.BroadcastCount, i, num);
\r
3714 PackAddInt64Ex(p, "Ex.Send.UnicastBytes", t->Send.UnicastBytes, i, num);
\r
3715 PackAddInt64Ex(p, "Ex.Send.UnicastCount", t->Send.UnicastCount, i, num);
\r
3719 void InRpcTraffic(TRAFFIC *t, PACK *p)
\r
3722 if (t == NULL || p == NULL)
\r
3727 Zero(t, sizeof(TRAFFIC));
\r
3728 t->Recv.BroadcastBytes = PackGetInt64(p, "Recv.BroadcastBytes");
\r
3729 t->Recv.BroadcastCount = PackGetInt64(p, "Recv.BroadcastCount");
\r
3730 t->Recv.UnicastBytes = PackGetInt64(p, "Recv.UnicastBytes");
\r
3731 t->Recv.UnicastCount = PackGetInt64(p, "Recv.UnicastCount");
\r
3732 t->Send.BroadcastBytes = PackGetInt64(p, "Send.BroadcastBytes");
\r
3733 t->Send.BroadcastCount = PackGetInt64(p, "Send.BroadcastCount");
\r
3734 t->Send.UnicastBytes = PackGetInt64(p, "Send.UnicastBytes");
\r
3735 t->Send.UnicastCount = PackGetInt64(p, "Send.UnicastCount");
\r
3737 void OutRpcTraffic(PACK *p, TRAFFIC *t)
\r
3740 if (t == NULL || p == NULL)
\r
3745 PackAddInt64(p, "Recv.BroadcastBytes", t->Recv.BroadcastBytes);
\r
3746 PackAddInt64(p, "Recv.BroadcastCount", t->Recv.BroadcastCount);
\r
3747 PackAddInt64(p, "Recv.UnicastBytes", t->Recv.UnicastBytes);
\r
3748 PackAddInt64(p, "Recv.UnicastCount", t->Recv.UnicastCount);
\r
3749 PackAddInt64(p, "Send.BroadcastBytes", t->Send.BroadcastBytes);
\r
3750 PackAddInt64(p, "Send.BroadcastCount", t->Send.BroadcastCount);
\r
3751 PackAddInt64(p, "Send.UnicastBytes", t->Send.UnicastBytes);
\r
3752 PackAddInt64(p, "Send.UnicastCount", t->Send.UnicastCount);
\r
3756 void InRpcCert(RPC_CERT *c, PACK *p)
\r
3760 if (c == NULL || p == NULL)
\r
3765 Zero(c, sizeof(RPC_CERT));
\r
3766 b = PackGetBuf(p, "x");
\r
3772 c->x = BufToX(b, false);
\r
3775 void OutRpcCert(PACK *p, RPC_CERT *c)
\r
3779 if (p == NULL || c == NULL)
\r
3786 b = XToBuf(c->x, false);
\r
3788 PackAddBuf(p, "x", b);
\r
3794 // RPC_CLIENT_DELETE_CA
\r
3795 void InRpcClientDeleteCa(RPC_CLIENT_DELETE_CA *c, PACK *p)
\r
3798 if (c == NULL || p == NULL)
\r
3803 Zero(c, sizeof(RPC_CLIENT_DELETE_CA));
\r
3804 c->Key = PackGetInt(p, "Key");
\r
3806 void OutRpcClientDeleteCa(PACK *p, RPC_CLIENT_DELETE_CA *c)
\r
3809 if (c == NULL || p == NULL)
\r
3814 PackAddInt(p, "Key", c->Key);
\r
3818 void InRpcGetCa(RPC_GET_CA *c, PACK *p)
\r
3822 if (c == NULL || p == NULL)
\r
3827 Zero(c, sizeof(RPC_GET_CA));
\r
3829 c->Key = PackGetInt(p, "Key");
\r
3831 b = PackGetBuf(p, "x");
\r
3834 c->x = BufToX(b, false);
\r
3839 void OutRpcGetCa(PACK *p, RPC_GET_CA *c)
\r
3842 if (c == NULL || p == NULL)
\r
3847 PackAddInt(p, "Key", c->Key);
\r
3851 BUF *b = XToBuf(c->x, false);
\r
3853 PackAddBuf(p, "x", b);
\r
3859 // RPC_CLIENT_ENUM_SECURE
\r
3860 void InRpcClientEnumSecure(RPC_CLIENT_ENUM_SECURE *e, PACK *p)
\r
3864 if (e == NULL || p == NULL)
\r
3869 Zero(e, sizeof(RPC_CLIENT_ENUM_SECURE));
\r
3871 e->NumItem = PackGetNum(p, "NumItem");
\r
3872 e->Items = ZeroMalloc(sizeof(RPC_CLIENT_ENUM_SECURE_ITEM *) * e->NumItem);
\r
3873 for (i = 0;i < e->NumItem;i++)
\r
3875 RPC_CLIENT_ENUM_SECURE_ITEM *item = e->Items[i] = ZeroMalloc(sizeof(RPC_CLIENT_ENUM_SECURE_ITEM));
\r
3877 item->DeviceId = PackGetIntEx(p, "DeviceId", i);
\r
3878 item->Type = PackGetIntEx(p, "Type", i);
\r
3879 PackGetStrEx(p, "DeviceName", item->DeviceName, sizeof(item->DeviceName), i);
\r
3880 PackGetStrEx(p, "Manufacturer", item->Manufacturer, sizeof(item->Manufacturer), i);
\r
3883 void OutRpcClientEnumSecure(PACK *p, RPC_CLIENT_ENUM_SECURE *e)
\r
3887 if (e == NULL || p == NULL)
\r
3892 PackAddNum(p, "NumItem", e->NumItem);
\r
3894 for (i = 0;i < e->NumItem;i++)
\r
3896 RPC_CLIENT_ENUM_SECURE_ITEM *item = e->Items[i];
\r
3898 PackAddIntEx(p, "DeviceId", item->DeviceId, i, e->NumItem);
\r
3899 PackAddIntEx(p, "Type", item->Type, i, e->NumItem);
\r
3900 PackAddStrEx(p, "DeviceName", item->DeviceName, i, e->NumItem);
\r
3901 PackAddStrEx(p, "Manufacturer", item->Manufacturer, i, e->NumItem);
\r
3906 void InRpcUseSecure(RPC_USE_SECURE *u, PACK *p)
\r
3909 if (u == NULL || p == NULL)
\r
3914 Zero(u, sizeof(RPC_USE_SECURE));
\r
3915 u->DeviceId = PackGetInt(p, "DeviceId");
\r
3917 void OutRpcUseSecure(PACK *p, RPC_USE_SECURE *u)
\r
3920 if (u == NULL || p == NULL)
\r
3925 PackAddInt(p, "DeviceId", u->DeviceId);
\r
3928 // RPC_ENUM_OBJECT_IN_SECURE の解放
\r
3929 void CiFreeEnumObjectInSecure(RPC_ENUM_OBJECT_IN_SECURE *a)
\r
3938 for (i = 0;i < a->NumItem;i++)
\r
3940 Free(a->ItemName[i]);
\r
3942 Free(a->ItemName);
\r
3943 Free(a->ItemType);
\r
3946 // RPC_ENUM_OBJECT_IN_SECURE
\r
3947 void InRpcEnumObjectInSecure(RPC_ENUM_OBJECT_IN_SECURE *e, PACK *p)
\r
3951 if (e == NULL || p == NULL)
\r
3956 Zero(e, sizeof(RPC_ENUM_OBJECT_IN_SECURE));
\r
3958 e->NumItem = PackGetNum(p, "NumItem");
\r
3959 e->hWnd = PackGetInt(p, "hWnd");
\r
3960 e->ItemName = ZeroMalloc(sizeof(char *) * e->NumItem);
\r
3961 e->ItemType = ZeroMalloc(sizeof(bool) * e->NumItem);
\r
3963 for (i = 0;i < e->NumItem;i++)
\r
3965 char name[MAX_SIZE];
\r
3967 Zero(name, sizeof(name));
\r
3968 PackGetStrEx(p, "ItemName", name, sizeof(name), i);
\r
3969 e->ItemName[i] = CopyStr(name);
\r
3971 e->ItemType[i] = PackGetIntEx(p, "ItemType", i) ? true : false;
\r
3974 void OutRpcEnumObjectInSecure(PACK *p, RPC_ENUM_OBJECT_IN_SECURE *e)
\r
3978 if (e == NULL || p == NULL)
\r
3983 PackAddNum(p, "NumItem", e->NumItem);
\r
3984 PackAddInt(p, "hWnd", e->hWnd);
\r
3986 for (i = 0;i < e->NumItem;i++)
\r
3988 PackAddStrEx(p, "ItemName", e->ItemName[i], i, e->NumItem);
\r
3989 PackAddIntEx(p, "ItemType", e->ItemType[i], i, e->NumItem);
\r
3993 // RPC_CLIENT_CREATE_VLAN
\r
3994 void InRpcCreateVLan(RPC_CLIENT_CREATE_VLAN *v, PACK *p)
\r
3997 if (v == NULL || p == NULL)
\r
4002 Zero(v, sizeof(RPC_CLIENT_CREATE_VLAN));
\r
4003 PackGetStr(p, "DeviceName", v->DeviceName, sizeof(v->DeviceName));
\r
4005 void OutRpcCreateVLan(PACK *p, RPC_CLIENT_CREATE_VLAN *v)
\r
4008 if (v == NULL || p == NULL)
\r
4013 PackAddStr(p, "DeviceName", v->DeviceName);
\r
4016 // RPC_CLIENT_GET_VLAN
\r
4017 void InRpcClientGetVLan(RPC_CLIENT_GET_VLAN *v, PACK *p)
\r
4020 if (v == NULL || p == NULL)
\r
4025 Zero(v, sizeof(RPC_CLIENT_GET_VLAN));
\r
4026 PackGetStr(p, "DeviceName", v->DeviceName, sizeof(v->DeviceName));
\r
4027 v->Enabled = PackGetInt(p, "Enabled") ? true : false;
\r
4028 PackGetStr(p, "MacAddress", v->MacAddress, sizeof(v->MacAddress));
\r
4029 PackGetStr(p, "Version", v->Version, sizeof(v->Version));
\r
4030 PackGetStr(p, "FileName", v->FileName, sizeof(v->FileName));
\r
4031 PackGetStr(p, "Guid", v->Guid, sizeof(v->Guid));
\r
4033 void OutRpcClientGetVLan(PACK *p, RPC_CLIENT_GET_VLAN *v)
\r
4036 if (v == NULL || p == NULL)
\r
4041 PackAddStr(p, "DeviceName", v->DeviceName);
\r
4042 PackAddInt(p, "Enabled", v->Enabled);
\r
4043 PackAddStr(p, "MacAddress", v->MacAddress);
\r
4044 PackAddStr(p, "Version", v->Version);
\r
4045 PackAddStr(p, "FileName", v->FileName);
\r
4046 PackAddStr(p, "Guid", v->Guid);
\r
4049 // RPC_CLIENT_SET_VLAN
\r
4050 void InRpcClientSetVLan(RPC_CLIENT_SET_VLAN *v, PACK *p)
\r
4053 if (v == NULL || p == NULL)
\r
4058 Zero(v, sizeof(RPC_CLIENT_SET_VLAN));
\r
4059 PackGetStr(p, "DeviceName", v->DeviceName, sizeof(v->DeviceName));
\r
4060 PackGetStr(p, "MacAddress", v->MacAddress, sizeof(v->MacAddress));
\r
4062 void OutRpcClientSetVLan(PACK *p, RPC_CLIENT_SET_VLAN *v)
\r
4065 if (v == NULL || p == NULL)
\r
4070 PackAddStr(p, "DeviceName", v->DeviceName);
\r
4071 PackAddStr(p, "MacAddress", v->MacAddress);
\r
4074 // RPC_CLIENT_ENUM_VLAN
\r
4075 void InRpcClientEnumVLan(RPC_CLIENT_ENUM_VLAN *v, PACK *p)
\r
4079 if (v == NULL || p == NULL)
\r
4084 Zero(v, sizeof(RPC_CLIENT_ENUM_VLAN));
\r
4085 v->NumItem = PackGetNum(p, "NumItem");
\r
4086 v->Items = ZeroMalloc(sizeof(RPC_CLIENT_ENUM_VLAN_ITEM *) * v->NumItem);
\r
4088 for (i = 0;i < v->NumItem;i++)
\r
4090 RPC_CLIENT_ENUM_VLAN_ITEM *item = v->Items[i] =
\r
4091 ZeroMalloc(sizeof(RPC_CLIENT_ENUM_VLAN_ITEM));
\r
4093 PackGetStrEx(p, "DeviceName", item->DeviceName, sizeof(item->DeviceName), i);
\r
4094 item->Enabled = PackGetIntEx(p, "Enabled", i) ? true : false;
\r
4095 PackGetStrEx(p, "MacAddress", item->MacAddress, sizeof(item->MacAddress), i);
\r
4096 PackGetStrEx(p, "Version", item->Version, sizeof(item->Version), i);
\r
4099 void OutRpcClientEnumVLan(PACK *p, RPC_CLIENT_ENUM_VLAN *v)
\r
4103 if (v == NULL || p == NULL)
\r
4108 PackAddNum(p, "NumItem", v->NumItem);
\r
4110 for (i = 0;i < v->NumItem;i++)
\r
4112 RPC_CLIENT_ENUM_VLAN_ITEM *item = v->Items[i];
\r
4114 PackAddStrEx(p, "DeviceName", item->DeviceName, i, v->NumItem);
\r
4115 PackAddIntEx(p, "Enabled", item->Enabled, i, v->NumItem);
\r
4116 PackAddStrEx(p, "MacAddress", item->MacAddress, i, v->NumItem);
\r
4117 PackAddStrEx(p, "Version", item->Version, i, v->NumItem);
\r
4122 void InRpcClientOption(CLIENT_OPTION *c, PACK *p)
\r
4125 if (c == NULL || p == NULL)
\r
4130 Zero(c, sizeof(CLIENT_OPTION));
\r
4132 PackGetUniStr(p, "AccountName", c->AccountName, sizeof(c->AccountName));
\r
4133 PackGetStr(p, "Hostname", c->Hostname, sizeof(c->Hostname));
\r
4134 c->Port = PackGetInt(p, "Port");
\r
4135 c->PortUDP = PackGetInt(p, "PortUDP");
\r
4136 c->ProxyType = PackGetInt(p, "ProxyType");
\r
4137 c->ProxyPort = PackGetInt(p, "ProxyPort");
\r
4138 c->NumRetry = PackGetInt(p, "NumRetry");
\r
4139 c->RetryInterval = PackGetInt(p, "RetryInterval");
\r
4140 c->MaxConnection = PackGetInt(p, "MaxConnection");
\r
4141 c->AdditionalConnectionInterval = PackGetInt(p, "AdditionalConnectionInterval");
\r
4142 c->ConnectionDisconnectSpan = PackGetInt(p, "ConnectionDisconnectSpan");
\r
4143 c->HideStatusWindow = PackGetBool(p, "HideStatusWindow");
\r
4144 c->HideNicInfoWindow = PackGetBool(p, "HideNicInfoWindow");
\r
4145 c->DisableQoS = PackGetBool(p, "DisableQoS");
\r
4146 PackGetStr(p, "ProxyName", c->ProxyName, sizeof(c->ProxyName));
\r
4147 PackGetStr(p, "ProxyUsername", c->ProxyUsername, sizeof(c->ProxyUsername));
\r
4148 PackGetStr(p, "ProxyPassword", c->ProxyPassword, sizeof(c->ProxyPassword));
\r
4149 PackGetStr(p, "HubName", c->HubName, sizeof(c->HubName));
\r
4150 PackGetStr(p, "DeviceName", c->DeviceName, sizeof(c->DeviceName));
\r
4151 c->UseEncrypt = PackGetInt(p, "UseEncrypt") ? true : false;
\r
4152 c->UseCompress = PackGetInt(p, "UseCompress") ? true : false;
\r
4153 c->HalfConnection = PackGetInt(p, "HalfConnection") ? true : false;
\r
4154 c->NoRoutingTracking = PackGetInt(p, "NoRoutingTracking") ? true : false;
\r
4155 c->RequireMonitorMode = PackGetBool(p, "RequireMonitorMode");
\r
4156 c->RequireBridgeRoutingMode = PackGetBool(p, "RequireBridgeRoutingMode");
\r
4157 c->FromAdminPack = PackGetBool(p, "FromAdminPack");
\r
4158 c->NoTls1 = PackGetBool(p, "NoTls1");
\r
4160 void OutRpcClientOption(PACK *p, CLIENT_OPTION *c)
\r
4163 if (c == NULL || p == NULL)
\r
4168 PackAddUniStr(p, "AccountName", c->AccountName);
\r
4169 PackAddStr(p, "Hostname", c->Hostname);
\r
4170 PackAddStr(p, "ProxyName", c->ProxyName);
\r
4171 PackAddStr(p, "ProxyUsername", c->ProxyUsername);
\r
4172 PackAddStr(p, "ProxyPassword", c->ProxyPassword);
\r
4173 PackAddStr(p, "HubName", c->HubName);
\r
4174 PackAddStr(p, "DeviceName", c->DeviceName);
\r
4175 PackAddInt(p, "Port", c->Port);
\r
4176 PackAddInt(p, "PortUDP", c->PortUDP);
\r
4177 PackAddInt(p, "ProxyType", c->ProxyType);
\r
4178 PackAddInt(p, "ProxyPort", c->ProxyPort);
\r
4179 PackAddInt(p, "NumRetry", c->NumRetry);
\r
4180 PackAddInt(p, "RetryInterval", c->RetryInterval);
\r
4181 PackAddInt(p, "MaxConnection", c->MaxConnection);
\r
4182 PackAddInt(p, "UseEncrypt", c->UseEncrypt);
\r
4183 PackAddInt(p, "UseCompress", c->UseCompress);
\r
4184 PackAddInt(p, "HalfConnection", c->HalfConnection);
\r
4185 PackAddInt(p, "NoRoutingTracking", c->NoRoutingTracking);
\r
4186 PackAddInt(p, "AdditionalConnectionInterval", c->AdditionalConnectionInterval);
\r
4187 PackAddInt(p, "ConnectionDisconnectSpan", c->ConnectionDisconnectSpan);
\r
4188 PackAddBool(p, "HideStatusWindow", c->HideStatusWindow);
\r
4189 PackAddBool(p, "HideNicInfoWindow", c->HideNicInfoWindow);
\r
4190 PackAddBool(p, "RequireMonitorMode", c->RequireMonitorMode);
\r
4191 PackAddBool(p, "RequireBridgeRoutingMode", c->RequireBridgeRoutingMode);
\r
4192 PackAddBool(p, "DisableQoS", c->DisableQoS);
\r
4193 PackAddBool(p, "FromAdminPack", c->FromAdminPack);
\r
4194 PackAddBool(p, "NoTls1", c->NoTls1);
\r
4198 void InRpcClientAuth(CLIENT_AUTH *c, PACK *p)
\r
4202 if (c == NULL || p == NULL)
\r
4207 Zero(c, sizeof(CLIENT_AUTH));
\r
4208 c->AuthType = PackGetInt(p, "AuthType");
\r
4209 PackGetStr(p, "Username", c->Username, sizeof(c->Username));
\r
4211 switch (c->AuthType)
\r
4213 case CLIENT_AUTHTYPE_ANONYMOUS:
\r
4216 case CLIENT_AUTHTYPE_PASSWORD:
\r
4217 if (PackGetDataSize(p, "HashedPassword") == SHA1_SIZE)
\r
4219 PackGetData(p, "HashedPassword", c->HashedPassword);
\r
4223 case CLIENT_AUTHTYPE_PLAIN_PASSWORD:
\r
4224 PackGetStr(p, "PlainPassword", c->PlainPassword, sizeof(c->PlainPassword));
\r
4227 case CLIENT_AUTHTYPE_CERT:
\r
4228 b = PackGetBuf(p, "ClientX");
\r
4231 c->ClientX = BufToX(b, false);
\r
4234 b = PackGetBuf(p, "ClientK");
\r
4237 c->ClientK = BufToK(b, true, false, NULL);
\r
4242 case CLIENT_AUTHTYPE_SECURE:
\r
4243 PackGetStr(p, "SecurePublicCertName", c->SecurePublicCertName, sizeof(c->SecurePublicCertName));
\r
4244 PackGetStr(p, "SecurePrivateKeyName", c->SecurePrivateKeyName, sizeof(c->SecurePrivateKeyName));
\r
4248 void OutRpcClientAuth(PACK *p, CLIENT_AUTH *c)
\r
4252 if (c == NULL || p == NULL)
\r
4257 PackAddInt(p, "AuthType", c->AuthType);
\r
4258 PackAddStr(p, "Username", c->Username);
\r
4260 switch (c->AuthType)
\r
4262 case CLIENT_AUTHTYPE_ANONYMOUS:
\r
4265 case CLIENT_AUTHTYPE_PASSWORD:
\r
4266 PackAddData(p, "HashedPassword", c->HashedPassword, SHA1_SIZE);
\r
4269 case CLIENT_AUTHTYPE_PLAIN_PASSWORD:
\r
4270 PackAddStr(p, "PlainPassword", c->PlainPassword);
\r
4273 case CLIENT_AUTHTYPE_CERT:
\r
4274 b = XToBuf(c->ClientX, false);
\r
4277 PackAddBuf(p, "ClientX", b);
\r
4280 b = KToBuf(c->ClientK, false, NULL);
\r
4283 PackAddBuf(p, "ClientK", b);
\r
4288 case CLIENT_AUTHTYPE_SECURE:
\r
4289 PackAddStr(p, "SecurePublicCertName", c->SecurePublicCertName);
\r
4290 PackAddStr(p, "SecurePrivateKeyName", c->SecurePrivateKeyName);
\r
4295 // RPC_CLIENT_CREATE_ACCOUNT
\r
4296 void InRpcClientCreateAccount(RPC_CLIENT_CREATE_ACCOUNT *c, PACK *p)
\r
4300 if (c == NULL || p == NULL)
\r
4305 Zero(c, sizeof(RPC_CLIENT_CREATE_ACCOUNT));
\r
4306 c->ClientOption = ZeroMalloc(sizeof(CLIENT_OPTION));
\r
4307 c->ClientAuth = ZeroMalloc(sizeof(CLIENT_AUTH));
\r
4309 InRpcClientOption(c->ClientOption, p);
\r
4310 InRpcClientAuth(c->ClientAuth, p);
\r
4312 c->StartupAccount = PackGetInt(p, "StartupAccount") ? true : false;
\r
4313 c->CheckServerCert = PackGetInt(p, "CheckServerCert") ? true : false;
\r
4314 b = PackGetBuf(p, "ServerCert");
\r
4317 c->ServerCert = BufToX(b, false);
\r
4320 PackGetData2(p, "ShortcutKey", c->ShortcutKey, sizeof(c->ShortcutKey));
\r
4322 void OutRpcClientCreateAccount(PACK *p, RPC_CLIENT_CREATE_ACCOUNT *c)
\r
4326 if (c == NULL || p == NULL)
\r
4331 OutRpcClientOption(p, c->ClientOption);
\r
4332 OutRpcClientAuth(p, c->ClientAuth);
\r
4334 PackAddInt(p, "StartupAccount", c->StartupAccount);
\r
4335 PackAddInt(p, "CheckServerCert", c->CheckServerCert);
\r
4336 if (c->ServerCert != NULL)
\r
4338 b = XToBuf(c->ServerCert, false);
\r
4341 PackAddBuf(p, "ServerCert", b);
\r
4345 PackAddData(p, "ShortcutKey", c->ShortcutKey, sizeof(c->ShortcutKey));
\r
4348 // RPC_CLIENT_ENUM_ACCOUNT
\r
4349 void InRpcClientEnumAccount(RPC_CLIENT_ENUM_ACCOUNT *e, PACK *p)
\r
4353 if (e == NULL || p == NULL)
\r
4358 Zero(e, sizeof(RPC_CLIENT_ENUM_ACCOUNT));
\r
4360 e->NumItem = PackGetNum(p, "NumItem");
\r
4361 e->Items = ZeroMalloc(sizeof(RPC_CLIENT_ENUM_ACCOUNT_ITEM *) * e->NumItem);
\r
4363 for (i = 0;i < e->NumItem;i++)
\r
4365 RPC_CLIENT_ENUM_ACCOUNT_ITEM *item = e->Items[i] =
\r
4366 ZeroMalloc(sizeof(RPC_CLIENT_ENUM_ACCOUNT_ITEM));
\r
4368 PackGetUniStrEx(p, "AccountName", item->AccountName, sizeof(item->AccountName), i);
\r
4369 PackGetStrEx(p, "UserName", item->UserName, sizeof(item->UserName), i);
\r
4370 PackGetStrEx(p, "ServerName", item->ServerName, sizeof(item->ServerName), i);
\r
4371 PackGetStrEx(p, "ProxyName", item->ProxyName, sizeof(item->ProxyName), i);
\r
4372 PackGetStrEx(p, "DeviceName", item->DeviceName, sizeof(item->DeviceName), i);
\r
4373 item->ProxyType = PackGetIntEx(p, "ProxyType", i);
\r
4374 item->Active = PackGetIntEx(p, "Active", i) ? true : false;
\r
4375 item->StartupAccount = PackGetIntEx(p, "StartupAccount", i) ? true : false;
\r
4376 item->Connected = PackGetBoolEx(p, "Connected", i);
\r
4377 item->Port = PackGetIntEx(p, "Port", i);
\r
4378 PackGetStrEx(p, "HubName", item->HubName, sizeof(item->HubName), i);
\r
4379 item->CreateDateTime = PackGetInt64Ex(p, "CreateDateTime", i);
\r
4380 item->UpdateDateTime = PackGetInt64Ex(p, "UpdateDateTime", i);
\r
4381 item->LastConnectDateTime = PackGetInt64Ex(p, "LastConnectDateTime", i);
\r
4384 void OutRpcClientEnumAccount(PACK *p, RPC_CLIENT_ENUM_ACCOUNT *e)
\r
4388 if (e == NULL || p == NULL)
\r
4393 PackAddNum(p, "NumItem", e->NumItem);
\r
4395 for (i = 0;i < e->NumItem;i++)
\r
4397 RPC_CLIENT_ENUM_ACCOUNT_ITEM *item = e->Items[i];
\r
4399 PackAddUniStrEx(p, "AccountName", item->AccountName, i, e->NumItem);
\r
4400 PackAddStrEx(p, "UserName", item->UserName, i, e->NumItem);
\r
4401 PackAddStrEx(p, "ServerName", item->ServerName, i, e->NumItem);
\r
4402 PackAddStrEx(p, "ProxyName", item->ProxyName, i, e->NumItem);
\r
4403 PackAddStrEx(p, "DeviceName", item->DeviceName, i, e->NumItem);
\r
4404 PackAddIntEx(p, "ProxyType", item->ProxyType, i, e->NumItem);
\r
4405 PackAddIntEx(p, "Active", item->Active, i, e->NumItem);
\r
4406 PackAddIntEx(p, "StartupAccount", item->StartupAccount, i, e->NumItem);
\r
4407 PackAddBoolEx(p, "Connected", item->Connected, i, e->NumItem);
\r
4408 PackAddIntEx(p, "Port", item->Port, i, e->NumItem);
\r
4409 PackAddStrEx(p, "HubName", item->HubName, i, e->NumItem);
\r
4410 PackAddInt64Ex(p, "CreateDateTime", item->CreateDateTime, i, e->NumItem);
\r
4411 PackAddInt64Ex(p, "UpdateDateTime", item->UpdateDateTime, i, e->NumItem);
\r
4412 PackAddInt64Ex(p, "LastConnectDateTime", item->LastConnectDateTime, i, e->NumItem);
\r
4416 // RPC_CLIENT_DELETE_ACCOUNT
\r
4417 void InRpcClientDeleteAccount(RPC_CLIENT_DELETE_ACCOUNT *a, PACK *p)
\r
4420 if (a == NULL || p == NULL)
\r
4425 Zero(a, sizeof(RPC_CLIENT_DELETE_ACCOUNT));
\r
4426 PackGetUniStr(p, "AccountName", a->AccountName, sizeof(a->AccountName));
\r
4428 void OutRpcClientDeleteAccount(PACK *p, RPC_CLIENT_DELETE_ACCOUNT *a)
\r
4431 if (a == NULL || p == NULL)
\r
4436 PackAddUniStr(p, "AccountName", a->AccountName);
\r
4439 // RPC_RENAME_ACCOUNT
\r
4440 void InRpcRenameAccount(RPC_RENAME_ACCOUNT *a, PACK *p)
\r
4443 if (a == NULL || p == NULL)
\r
4448 Zero(a, sizeof(RPC_RENAME_ACCOUNT));
\r
4450 PackGetUniStr(p, "OldName", a->OldName, sizeof(a->OldName));
\r
4451 PackGetUniStr(p, "NewName", a->NewName, sizeof(a->NewName));
\r
4453 void OutRpcRenameAccount(PACK *p, RPC_RENAME_ACCOUNT *a)
\r
4456 if (a == NULL || p == NULL)
\r
4461 PackAddUniStr(p, "OldName", a->OldName);
\r
4462 PackAddUniStr(p, "NewName", a->NewName);
\r
4465 // RPC_CLIENT_GET_ACCOUNT
\r
4466 void InRpcClientGetAccount(RPC_CLIENT_GET_ACCOUNT *c, PACK *p)
\r
4470 if (c == NULL || p == NULL)
\r
4475 Zero(c, sizeof(RPC_CLIENT_GET_ACCOUNT));
\r
4477 c->ClientOption = ZeroMalloc(sizeof(CLIENT_OPTION));
\r
4478 c->ClientAuth = ZeroMalloc(sizeof(CLIENT_AUTH));
\r
4480 PackGetUniStr(p, "AccountName", c->AccountName, sizeof(c->AccountName));
\r
4481 c->StartupAccount = PackGetInt(p, "StartupAccount") ? true : false;
\r
4482 c->CheckServerCert = PackGetInt(p, "CheckServerCert") ? true : false;
\r
4483 b = PackGetBuf(p, "ServerCert");
\r
4486 c->ServerCert = BufToX(b, false);
\r
4490 InRpcClientOption(c->ClientOption, p);
\r
4491 InRpcClientAuth(c->ClientAuth, p);
\r
4493 c->CreateDateTime = PackGetInt64(p, "CreateDateTime");
\r
4494 c->UpdateDateTime = PackGetInt64(p, "UpdateDateTime");
\r
4495 c->LastConnectDateTime = PackGetInt64(p, "LastConnectDateTime");
\r
4497 PackGetData2(p, "ShortcutKey", c->ShortcutKey, SHA1_SIZE);
\r
4499 void OutRpcClientGetAccount(PACK *p, RPC_CLIENT_GET_ACCOUNT *c)
\r
4503 if (c == NULL || p == NULL)
\r
4508 PackAddUniStr(p, "AccountName", c->AccountName);
\r
4509 PackAddInt(p, "StartupAccount", c->StartupAccount);
\r
4510 PackAddInt(p, "CheckServerCert", c->CheckServerCert);
\r
4512 if (c->ServerCert != NULL)
\r
4514 b = XToBuf(c->ServerCert, false);
\r
4517 PackAddBuf(p, "ServerCert", b);
\r
4522 OutRpcClientOption(p, c->ClientOption);
\r
4523 OutRpcClientAuth(p, c->ClientAuth);
\r
4525 PackAddData(p, "ShortcutKey", c->ShortcutKey, SHA1_SIZE);
\r
4527 PackAddInt64(p, "CreateDateTime", c->CreateDateTime);
\r
4528 PackAddInt64(p, "UpdateDateTime", c->UpdateDateTime);
\r
4529 PackAddInt64(p, "LastConnectDateTime", c->LastConnectDateTime);
\r
4532 // RPC_CLIENT_CONNECT
\r
4533 void InRpcClientConnect(RPC_CLIENT_CONNECT *c, PACK *p)
\r
4536 if (c == NULL || p == NULL)
\r
4541 Zero(c, sizeof(RPC_CLIENT_CONNECT));
\r
4543 PackGetUniStr(p, "AccountName", c->AccountName, sizeof(c->AccountName));
\r
4545 void OutRpcClientConnect(PACK *p, RPC_CLIENT_CONNECT *c)
\r
4548 if (c == NULL || p == NULL)
\r
4553 PackAddUniStr(p, "AccountName", c->AccountName);
\r
4557 void InRpcPolicy(POLICY *o, PACK *p)
\r
4561 if (o == NULL || p == NULL)
\r
4566 pol = PackGetPolicy(p);
\r
4567 Copy(o, pol, sizeof(POLICY));
\r
4570 void OutRpcPolicy(PACK *p, POLICY *o)
\r
4573 if (o == NULL || p == NULL)
\r
4578 PackAddPolicy(p, o);
\r
4581 // RPC_CLIENT_GET_CONNECTION_STATUS
\r
4582 void InRpcClientGetConnectionStatus(RPC_CLIENT_GET_CONNECTION_STATUS *s, PACK *p)
\r
4586 if (s == NULL || p == NULL)
\r
4591 Zero(s, sizeof(RPC_CLIENT_GET_CONNECTION_STATUS));
\r
4593 PackGetUniStr(p, "AccountName", s->AccountName, sizeof(s->AccountName));
\r
4595 PackGetStr(p, "ServerName", s->ServerName, sizeof(s->ServerName));
\r
4596 PackGetStr(p, "ServerProductName", s->ServerProductName, sizeof(s->ServerProductName));
\r
4597 PackGetStr(p, "CipherName", s->CipherName, sizeof(s->CipherName));
\r
4598 PackGetStr(p, "SessionName", s->SessionName, sizeof(s->SessionName));
\r
4599 PackGetStr(p, "ConnectionName", s->ConnectionName, sizeof(s->ConnectionName));
\r
4601 if (PackGetDataSize(p, "SessionKey") == SHA1_SIZE)
\r
4603 PackGetData(p, "SessionKey", s->SessionKey);
\r
4606 s->SessionStatus = PackGetInt(p, "SessionStatus");
\r
4607 s->ServerPort = PackGetInt(p, "ServerPort");
\r
4608 s->ServerProductVer = PackGetInt(p, "ServerProductVer");
\r
4609 s->ServerProductBuild = PackGetInt(p, "ServerProductBuild");
\r
4610 s->NumConnectionsEatablished = PackGetInt(p, "NumConnectionsEatablished");
\r
4611 s->MaxTcpConnections = PackGetInt(p, "MaxTcpConnections");
\r
4612 s->NumTcpConnections = PackGetInt(p, "NumTcpConnections");
\r
4613 s->NumTcpConnectionsUpload = PackGetInt(p, "NumTcpConnectionsUpload");
\r
4614 s->NumTcpConnectionsDownload = PackGetInt(p, "NumTcpConnectionsDownload");
\r
4616 s->StartTime = PackGetInt64(p, "StartTime");
\r
4617 s->FirstConnectionEstablisiedTime = PackGetInt64(p, "FirstConnectionEstablisiedTime");
\r
4618 s->CurrentConnectionEstablishTime = PackGetInt64(p, "CurrentConnectionEstablishTime");
\r
4619 s->TotalSendSize = PackGetInt64(p, "TotalSendSize");
\r
4620 s->TotalRecvSize = PackGetInt64(p, "TotalRecvSize");
\r
4621 s->TotalSendSizeReal = PackGetInt64(p, "TotalSendSizeReal");
\r
4622 s->TotalRecvSizeReal = PackGetInt64(p, "TotalRecvSizeReal");
\r
4624 s->Active = PackGetInt(p, "Active") ? true : false;
\r
4625 s->Connected = PackGetInt(p, "Connected") ? true : false;
\r
4626 s->HalfConnection = PackGetInt(p, "HalfConnection") ? true : false;
\r
4627 s->QoS = PackGetInt(p, "QoS") ? true : false;
\r
4628 s->UseEncrypt = PackGetInt(p, "UseEncrypt") ? true : false;
\r
4629 s->UseCompress = PackGetInt(p, "UseCompress") ? true : false;
\r
4631 s->IsBridgeMode = PackGetBool(p, "IsBridgeMode");
\r
4632 s->IsMonitorMode = PackGetBool(p, "IsMonitorMode");
\r
4634 s->VLanId = PackGetInt(p, "VLanId");
\r
4636 b = PackGetBuf(p, "ServerX");
\r
4639 s->ServerX = BufToX(b, false);
\r
4643 b = PackGetBuf(p, "ClientX");
\r
4646 s->ClientX = BufToX(b, false);
\r
4650 InRpcPolicy(&s->Policy, p);
\r
4652 InRpcTraffic(&s->Traffic, p);
\r
4654 void OutRpcClientGetConnectionStatus(PACK *p, RPC_CLIENT_GET_CONNECTION_STATUS *c)
\r
4658 if (p == NULL || c == NULL)
\r
4663 PackAddUniStr(p, "AccountName", c->AccountName);
\r
4665 PackAddStr(p, "ServerName", c->ServerName);
\r
4666 PackAddStr(p, "ServerProductName", c->ServerProductName);
\r
4667 PackAddStr(p, "CipherName", c->CipherName);
\r
4668 PackAddStr(p, "SessionName", c->SessionName);
\r
4669 PackAddStr(p, "ConnectionName", c->ConnectionName);
\r
4671 PackAddData(p, "SessionKey", c->SessionKey, SHA1_SIZE);
\r
4673 PackAddInt(p, "Active", c->Active);
\r
4674 PackAddInt(p, "Connected", c->Connected);
\r
4675 PackAddInt(p, "SessionStatus", c->SessionStatus);
\r
4676 PackAddInt(p, "ServerPort", c->ServerPort);
\r
4677 PackAddInt(p, "ServerProductVer", c->ServerProductVer);
\r
4678 PackAddInt(p, "ServerProductBuild", c->ServerProductBuild);
\r
4679 PackAddInt(p, "NumConnectionsEatablished", c->NumConnectionsEatablished);
\r
4680 PackAddInt(p, "HalfConnection", c->HalfConnection);
\r
4681 PackAddInt(p, "QoS", c->QoS);
\r
4682 PackAddInt(p, "MaxTcpConnections", c->MaxTcpConnections);
\r
4683 PackAddInt(p, "NumTcpConnections", c->NumTcpConnections);
\r
4684 PackAddInt(p, "NumTcpConnectionsUpload", c->NumTcpConnectionsUpload);
\r
4685 PackAddInt(p, "NumTcpConnectionsDownload", c->NumTcpConnectionsDownload);
\r
4686 PackAddInt(p, "UseEncrypt", c->UseEncrypt);
\r
4687 PackAddInt(p, "UseCompress", c->UseCompress);
\r
4689 PackAddBool(p, "IsBridgeMode", c->IsBridgeMode);
\r
4690 PackAddBool(p, "IsMonitorMode", c->IsMonitorMode);
\r
4692 PackAddInt64(p, "StartTime", c->StartTime);
\r
4693 PackAddInt64(p, "FirstConnectionEstablisiedTime", c->FirstConnectionEstablisiedTime);
\r
4694 PackAddInt64(p, "CurrentConnectionEstablishTime", c->CurrentConnectionEstablishTime);
\r
4695 PackAddInt64(p, "TotalSendSize", c->TotalSendSize);
\r
4696 PackAddInt64(p, "TotalRecvSize", c->TotalRecvSize);
\r
4697 PackAddInt64(p, "TotalSendSizeReal", c->TotalSendSizeReal);
\r
4698 PackAddInt64(p, "TotalRecvSizeReal", c->TotalRecvSizeReal);
\r
4700 PackAddInt(p, "VLanId", c->VLanId);
\r
4702 OutRpcPolicy(p, &c->Policy);
\r
4704 OutRpcTraffic(p, &c->Traffic);
\r
4706 if (c->ServerX != NULL)
\r
4708 b = XToBuf(c->ServerX, false);
\r
4709 PackAddBuf(p, "ServerX", b);
\r
4713 if (c->ClientX != NULL)
\r
4715 b = XToBuf(c->ClientX, false);
\r
4716 PackAddBuf(p, "ClientX", b);
\r
4721 void InRpcClientNotify(RPC_CLIENT_NOTIFY *n, PACK *p)
\r
4724 if (n == NULL || p == NULL)
\r
4729 Zero(n, sizeof(RPC_CLIENT_NOTIFY));
\r
4731 n->NotifyCode = PackGetInt(p, "NotifyCode");
\r
4733 void OutRpcClientNotify(PACK *p, RPC_CLIENT_NOTIFY *n)
\r
4736 if (n == NULL || p == NULL)
\r
4741 PackAddInt(p, "NotifyCode", n->NotifyCode);
\r
4745 void CiNotifyMain(CLIENT *c, SOCK *s)
\r
4749 if (c == NULL || s == NULL)
\r
4755 cancel = NewCancel();
\r
4756 LockList(c->NotifyCancelList);
\r
4758 Add(c->NotifyCancelList, cancel);
\r
4760 UnlockList(c->NotifyCancelList);
\r
4767 InitSockSet(&set);
\r
4768 AddSockSet(&set, s);
\r
4769 Select(&set, INFINITE, cancel, NULL);
\r
4778 if (Send(s, &ch, 1, false) == 0)
\r
4789 LockList(c->NotifyCancelList);
\r
4791 Delete(c->NotifyCancelList, cancel);
\r
4793 UnlockList(c->NotifyCancelList);
\r
4795 ReleaseCancel(cancel);
\r
4799 void CiRpcAccepted(CLIENT *c, SOCK *s)
\r
4801 UCHAR hashed_password[SHA1_SIZE];
\r
4806 if (c == NULL || s == NULL)
\r
4812 if (RecvAll(s, &rpc_mode, sizeof(UINT), false) == false)
\r
4817 rpc_mode = Endian32(rpc_mode);
\r
4819 if (rpc_mode == CLIENT_RPC_MODE_NOTIFY)
\r
4822 CiNotifyMain(c, s);
\r
4825 else if (rpc_mode == CLIENT_RPC_MODE_SHORTCUT || rpc_mode == CLIENT_RPC_MODE_SHORTCUT_DISCONNECT)
\r
4828 UCHAR key[SHA1_SIZE];
\r
4829 UINT err = ERR_NO_ERROR;
\r
4830 if (RecvAll(s, key, SHA1_SIZE, false))
\r
4833 wchar_t title[MAX_ACCOUNT_NAME_LEN + 1];
\r
4836 LockList(c->AccountList);
\r
4838 for (i = 0;i < LIST_NUM(c->AccountList);i++)
\r
4840 ACCOUNT *a = LIST_DATA(c->AccountList, i);
\r
4843 if (Cmp(a->ShortcutKey, key, SHA1_SIZE) == 0)
\r
4846 UniStrCpy(title, sizeof(title), a->ClientOption->AccountName);
\r
4852 UnlockList(c->AccountList);
\r
4856 err = ERR_ACCOUNT_NOT_FOUND;
\r
4860 RPC_CLIENT_CONNECT t;
\r
4861 Zero(&t, sizeof(t));
\r
4862 UniStrCpy(t.AccountName, sizeof(t.AccountName), title);
\r
4864 if (rpc_mode == CLIENT_RPC_MODE_SHORTCUT)
\r
4867 if (CtConnect(c, &t))
\r
4869 err = ERR_NO_ERROR;
\r
4879 if (CtDisconnect(c, &t))
\r
4881 err = ERR_NO_ERROR;
\r
4890 err = Endian32(err);
\r
4891 SendAll(s, &err, sizeof(UINT), false);
\r
4892 RecvAll(s, &err, sizeof(UINT), false);
\r
4898 if (RecvAll(s, hashed_password, SHA1_SIZE, false) == false)
\r
4906 if (Cmp(hashed_password, c->EncryptedPassword, SHA1_SIZE) != 0)
\r
4911 if (c->PasswordRemoteOnly && s->RemoteIP.addr[0] == 127)
\r
4913 // リモートのみパスワードを要求するモードで、ローカルから接続された場合は
\r
4914 // パスワードを常に正しいと見なす
\r
4920 if (c->Config.AllowRemoteConfig == false)
\r
4922 // リモート管理が禁止されている場合は
\r
4923 // このコネクションが外部からのものであるかどうか識別する
\r
4924 if (s->RemoteIP.addr[0] != 127)
\r
4932 retcode = Endian32(retcode);
\r
4934 if (SendAll(s, &retcode, sizeof(UINT), false) == false)
\r
4948 rpc = StartRpcServer(s, CiRpcDispatch, c);
\r
4958 void CiRpcAcceptThread(THREAD *thread, void *param)
\r
4960 CLIENT_RPC_CONNECTION *conn;
\r
4964 if (thread == NULL || param == NULL)
\r
4969 conn = (CLIENT_RPC_CONNECTION *)param;
\r
4974 // RPC コネクションリストに追加
\r
4975 LockList(c->RpcConnectionList);
\r
4977 Add(c->RpcConnectionList, conn);
\r
4979 UnlockList(c->RpcConnectionList);
\r
4981 NoticeThreadInit(thread);
\r
4984 CiRpcAccepted(c, s);
\r
4987 LockList(c->RpcConnectionList);
\r
4989 Delete(c->RpcConnectionList, conn);
\r
4991 UnlockList(c->RpcConnectionList);
\r
4993 ReleaseSock(conn->Sock);
\r
4994 ReleaseThread(conn->Thread);
\r
5002 void CiRpcServerThread(THREAD *thread, void *param)
\r
5007 LIST *thread_list;
\r
5009 if (thread == NULL || param == NULL)
\r
5014 c = (CLIENT *)param;
\r
5017 c->RpcConnectionList = NewList(NULL);
\r
5021 for (i = CLIENT_CONFIG_PORT;i < (CLIENT_CONFIG_PORT + 5);i++)
\r
5023 listener = Listen(i);
\r
5024 if (listener != NULL)
\r
5030 if (listener == NULL)
\r
5033 Alert("SoftEther UT-VPN Client RPC Port Open Failed.", CEDAR_CLIENT_STR);
\r
5037 c->RpcListener = listener;
\r
5038 AddRef(listener->ref);
\r
5040 NoticeThreadInit(thread);
\r
5045 CLIENT_RPC_CONNECTION *conn;
\r
5046 SOCK *s = Accept(listener);
\r
5053 // クライアント処理用スレッドを作成する
\r
5054 conn = ZeroMalloc(sizeof(CLIENT_RPC_CONNECTION));
\r
5059 conn->Thread = NewThread(CiRpcAcceptThread, (void *)conn);
\r
5060 WaitThreadInit(conn->Thread);
\r
5066 ReleaseSock(listener);
\r
5068 thread_list = NewListFast(NULL);
\r
5070 // すべての通知イベントを起動する
\r
5071 LockList(c->NotifyCancelList);
\r
5074 for (i = 0;i < LIST_NUM(c->NotifyCancelList);i++)
\r
5076 CANCEL *cancel = LIST_DATA(c->NotifyCancelList, i);
\r
5080 UnlockList(c->NotifyCancelList);
\r
5082 // まだ接続しているすべてのコネクションを切断する
\r
5083 LockList(c->RpcConnectionList);
\r
5085 for (i = 0;i < LIST_NUM(c->RpcConnectionList);i++)
\r
5087 CLIENT_RPC_CONNECTION *cc = LIST_DATA(c->RpcConnectionList, i);
\r
5088 AddRef(cc->Thread->ref);
\r
5089 Add(thread_list, cc->Thread);
\r
5090 Disconnect(cc->Sock);
\r
5093 UnlockList(c->RpcConnectionList);
\r
5095 for (i = 0;i < LIST_NUM(thread_list);i++)
\r
5097 THREAD *t = LIST_DATA(thread_list, i);
\r
5098 WaitThread(t, INFINITE);
\r
5102 ReleaseList(c->RpcConnectionList);
\r
5103 ReleaseList(thread_list);
\r
5107 void CiInitKeep(CLIENT *c)
\r
5115 c->Keep = StartKeep();
\r
5118 if (c->Config.UseKeepConnect)
\r
5120 KEEP *k = c->Keep;
\r
5123 StrCpy(k->ServerName, sizeof(k->ServerName), c->Config.KeepConnectHost);
\r
5124 k->ServerPort = c->Config.KeepConnectPort;
\r
5125 k->Interval = c->Config.KeepConnectInterval * 1000;
\r
5126 k->UdpMode = (c->Config.KeepConnectProtocol == CONNECTION_UDP) ? true : false;
\r
5134 void CiFreeKeep(CLIENT *c)
\r
5142 StopKeep(c->Keep);
\r
5147 void CiStartRpcServer(CLIENT *c)
\r
5155 c->RpcThread = NewThread(CiRpcServerThread, (void *)c);
\r
5156 WaitThreadInit(c->RpcThread);
\r
5160 void CiStopRpcServer(CLIENT *c)
\r
5168 Disconnect(c->RpcListener);
\r
5169 ReleaseSock(c->RpcListener);
\r
5171 WaitThread(c->RpcThread, INFINITE);
\r
5172 ReleaseThread(c->RpcThread);
\r
5176 bool CcWaitNotify(NOTIFY_CLIENT *n)
\r
5186 if (RecvAll(n->Sock, &c, 1, false) == false)
\r
5195 // 通知クライアントとして接続する
\r
5196 NOTIFY_CLIENT *CcConnectNotify(REMOTE_CLIENT *rc)
\r
5200 char tmp[MAX_SIZE];
\r
5201 bool rpc_mode = false;
\r
5204 if (rc == NULL || rc->Rpc == NULL || rc->Rpc->Sock == NULL)
\r
5210 IPToStr(tmp, sizeof(tmp), &rc->Rpc->Sock->RemoteIP);
\r
5211 port = rc->Rpc->Sock->RemotePort;
\r
5213 s = Connect(tmp, port);
\r
5219 rpc_mode = Endian32(rpc_mode);
\r
5220 if (SendAll(s, &rpc_mode, sizeof(rpc_mode), false) == false)
\r
5226 n = ZeroMalloc(sizeof(NOTIFY_CLIENT));
\r
5233 void CcStopNotify(NOTIFY_CLIENT *n)
\r
5241 Disconnect(n->Sock);
\r
5245 void CcDisconnectNotify(NOTIFY_CLIENT *n)
\r
5254 Disconnect(n->Sock);
\r
5255 ReleaseSock(n->Sock);
\r
5262 void CcDisconnectRpc(REMOTE_CLIENT *rc)
\r
5274 // クライアントに接続しショートカット接続設定を起動する
\r
5275 UINT CcShortcut(UCHAR *key)
\r
5281 return ERR_INVALID_PARAMETER;
\r
5284 CcConnectRpcEx("localhost", NULL, NULL, NULL, key, &ret, false, 0);
\r
5289 // 接続中のショートカット接続を切断する
\r
5290 UINT CcShortcutDisconnect(UCHAR *key)
\r
5296 return ERR_INVALID_PARAMETER;
\r
5299 CcConnectRpcEx("localhost", NULL, NULL, NULL, key, &ret, true, 0);
\r
5304 // クライアントにリモート接続する
\r
5305 REMOTE_CLIENT *CcConnectRpc(char *server_name, char *password, bool *bad_pass, bool *no_remote, UINT wait_retry)
\r
5307 return CcConnectRpcEx(server_name, password, bad_pass, no_remote, NULL, NULL, false, wait_retry);
\r
5309 REMOTE_CLIENT *CcConnectRpcEx(char *server_name, char *password, bool *bad_pass, bool *no_remote, UCHAR *key, UINT *key_error_code, bool shortcut_disconnect, UINT wait_retry)
\r
5314 UINT rpc_mode = CLIENT_RPC_MODE_MANAGEMENT;
\r
5316 REMOTE_CLIENT *ret;
\r
5317 UCHAR hash_password[SHA1_SIZE];
\r
5319 UINT64 try_started = 0;
\r
5322 if (server_name == NULL)
\r
5326 if (password == NULL)
\r
5331 if (key_error_code != NULL)
\r
5333 *key_error_code = ERR_NO_ERROR;
\r
5336 if (bad_pass != NULL)
\r
5338 *bad_pass = false;
\r
5341 if (no_remote != NULL)
\r
5343 *no_remote = false;
\r
5346 port_start = CLIENT_CONFIG_PORT - 1;
\r
5351 if (port_start >= (CLIENT_CONFIG_PORT + 5))
\r
5360 for (i = port_start;i < (CLIENT_CONFIG_PORT + 5);i++)
\r
5362 if (CheckTCPPort(server_name, i))
\r
5374 if (wait_retry == 0)
\r
5379 if (try_started == 0)
\r
5381 try_started = Tick64();
\r
5384 if ((try_started + (UINT64)wait_retry) <= Tick64())
\r
5392 if (key_error_code)
\r
5394 *key_error_code = ERR_CONNECT_FAILED;
\r
5401 s = Connect(server_name, i);
\r
5404 if (key_error_code)
\r
5406 *key_error_code = ERR_CONNECT_FAILED;
\r
5411 Hash(hash_password, password, StrLen(password), true);
\r
5415 if (shortcut_disconnect == false)
\r
5417 rpc_mode = CLIENT_RPC_MODE_SHORTCUT;
\r
5421 rpc_mode = CLIENT_RPC_MODE_SHORTCUT_DISCONNECT;
\r
5425 rpc_mode = Endian32(rpc_mode);
\r
5426 SendAdd(s, &rpc_mode, sizeof(UINT));
\r
5430 SendAdd(s, key, SHA1_SIZE);
\r
5434 SendAdd(s, hash_password, SHA1_SIZE);
\r
5437 if (SendNow(s, false) == false)
\r
5443 if (RecvAll(s, &retcode, sizeof(UINT), false) == false)
\r
5449 retcode = Endian32(retcode);
\r
5451 if (retcode >= 1024)
\r
5458 if (key_error_code)
\r
5460 *key_error_code = retcode;
\r
5462 SendAll(s, &retcode, sizeof(UINT), false);
\r
5470 if (bad_pass != NULL)
\r
5476 if (no_remote != NULL)
\r
5478 *no_remote = true;
\r
5489 rpc = StartRpcClient(s, NULL);
\r
5493 ret = ZeroMalloc(sizeof(REMOTE_CLIENT));
\r
5499 RPC_CLIENT_VERSION t;
\r
5500 Zero(&t, sizeof(t));
\r
5501 CcGetClientVersion(ret, &t);
\r
5502 ret->OsType = t.OsType;
\r
5503 ret->Unix = OS_IS_UNIX(ret->OsType);
\r
5504 ret->Win9x = OS_IS_WINDOWS_9X(ret->OsType);
\r
5510 // セッションから RPC_CLIENT_GET_CONNECTION_STATUS を取得
\r
5511 void CiGetSessionStatus(RPC_CLIENT_GET_CONNECTION_STATUS *st, SESSION *s)
\r
5514 if (st == NULL || s == NULL)
\r
5522 st->Active = true;
\r
5525 st->SessionStatus = s->ClientStatus;
\r
5528 UniStrCpy(st->AccountName, sizeof(st->AccountName), s->ClientOption->AccountName);
\r
5530 if (s->ClientStatus == CLIENT_STATUS_ESTABLISHED && s->Connection != NULL)
\r
5532 Lock(s->Connection->lock);
\r
5535 st->Connected = true;
\r
5537 StrCpy(st->ServerProductName, sizeof(st->ServerProductName), s->Connection->ServerStr);
\r
5539 st->ServerProductVer = s->Connection->ServerVer;
\r
5541 st->ServerProductBuild = s->Connection->ServerBuild;
\r
5543 st->ServerX = CloneX(s->Connection->ServerX);
\r
5545 st->ClientX = CloneX(s->Connection->ClientX);
\r
5546 // このコネクションの接続完了時刻
\r
5547 st->CurrentConnectionEstablishTime = TickToTime(s->CurrentConnectionEstablishTime);
\r
5548 // 最大の TCP コネクション数
\r
5549 st->MaxTcpConnections = s->MaxConnection;
\r
5551 st->HalfConnection = s->HalfConnection;
\r
5553 st->VLanId = s->VLanId;
\r
5556 if (s->Connection->Protocol == CONNECTION_TCP)
\r
5559 // 現在の TCP コネクション数
\r
5560 LockList(s->Connection->Tcp->TcpSockList);
\r
5562 st->NumTcpConnections = LIST_NUM(s->Connection->Tcp->TcpSockList);
\r
5563 if (st->HalfConnection)
\r
5565 for (i = 0;i < st->NumTcpConnections;i++)
\r
5567 TCPSOCK *ts = LIST_DATA(s->Connection->Tcp->TcpSockList, i);
\r
5568 if (ts->Direction & TCP_SERVER_TO_CLIENT)
\r
5570 st->NumTcpConnectionsDownload++;
\r
5574 st->NumTcpConnectionsUpload++;
\r
5579 UnlockList(s->Connection->Tcp->TcpSockList);
\r
5582 st->UseEncrypt = s->UseEncrypt;
\r
5583 if (st->UseEncrypt)
\r
5585 StrCpy(st->CipherName, sizeof(st->CipherName), s->Connection->CipherName);
\r
5588 st->UseCompress = s->UseCompress;
\r
5590 Copy(st->SessionKey, s->SessionKey, SHA1_SIZE);
\r
5592 Copy(&st->Policy, s->Policy, sizeof(POLICY));
\r
5594 if (s->ServerMode == false)
\r
5596 st->TotalSendSize = s->TotalSendSize;
\r
5597 st->TotalRecvSize = s->TotalRecvSize;
\r
5598 st->TotalRecvSizeReal = s->TotalRecvSizeReal;
\r
5599 st->TotalSendSizeReal = s->TotalSendSizeReal;
\r
5603 st->TotalSendSize = s->TotalRecvSize;
\r
5604 st->TotalRecvSize = s->TotalSendSize;
\r
5605 st->TotalRecvSizeReal = s->TotalSendSizeReal;
\r
5606 st->TotalSendSizeReal = s->TotalRecvSizeReal;
\r
5609 StrCpy(st->SessionName, sizeof(st->SessionName), s->Name);
\r
5611 StrCpy(st->ConnectionName, sizeof(st->ConnectionName), s->Connection->Name);
\r
5613 StrCpy(st->ServerName, sizeof(st->ServerName), s->Connection->ServerName);
\r
5615 st->ServerPort = s->Connection->ServerPort;
\r
5617 Lock(s->TrafficLock);
\r
5619 Copy(&st->Traffic, s->Traffic, sizeof(TRAFFIC));
\r
5621 Unlock(s->TrafficLock);
\r
5623 st->IsBridgeMode = s->IsBridgeMode;
\r
5624 st->IsMonitorMode = s->IsMonitorMode;
\r
5626 Unlock(s->Connection->lock);
\r
5629 st->StartTime = TickToTime(s->CreatedTime);
\r
5630 // 最初のコネクションの接続完了時刻
\r
5631 st->FirstConnectionEstablisiedTime = TickToTime(s->FirstConnectionEstablisiedTime);
\r
5632 // これまでに確立したコネクション数
\r
5633 st->NumConnectionsEatablished = s->NumConnectionsEatablished;
\r
5639 bool CtGetAccountStatus(CLIENT *c, RPC_CLIENT_GET_CONNECTION_STATUS *st)
\r
5642 if (c == NULL || st == NULL)
\r
5647 LockList(c->AccountList);
\r
5652 t.ClientOption = ZeroMalloc(sizeof(CLIENT_OPTION));
\r
5653 UniStrCpy(t.ClientOption->AccountName, sizeof(t.ClientOption->AccountName), st->AccountName);
\r
5655 r = Search(c->AccountList, &t);
\r
5658 // 指定したアカウントは見つからない
\r
5659 UnlockList(c->AccountList);
\r
5661 Free(t.ClientOption);
\r
5662 CiSetError(c, ERR_ACCOUNT_NOT_FOUND);
\r
5666 Free(t.ClientOption);
\r
5670 Zero(st, sizeof(RPC_CLIENT_GET_CONNECTION_STATUS));
\r
5671 if (r->ClientSession != NULL)
\r
5673 SESSION *s = r->ClientSession;
\r
5674 CiGetSessionStatus(st, s);
\r
5679 UnlockList(c->AccountList);
\r
5685 void CiFreeClientGetConnectionStatus(RPC_CLIENT_GET_CONNECTION_STATUS *st)
\r
5693 if (st->ServerX != NULL)
\r
5695 FreeX(st->ServerX);
\r
5698 if (st->ClientX != NULL)
\r
5700 FreeX(st->ClientX);
\r
5704 // サーバー証明書の確認プロシージャ
\r
5705 bool CiCheckCertProc(SESSION *s, CONNECTION *c, X *server_x, bool *expired)
\r
5712 if (s == NULL || c == NULL || server_x == NULL)
\r
5717 if (expired != NULL)
\r
5722 Zero(&dlg, sizeof(dlg));
\r
5732 if (a->CheckServerCert == false)
\r
5739 if (a->ServerCert != NULL)
\r
5741 old_x = CloneX(a->ServerCert);
\r
5746 if (CheckXDateNow(server_x) == false)
\r
5749 if (old_x != NULL)
\r
5754 if (expired != NULL)
\r
5762 if (old_x != NULL)
\r
5764 if (CompareX(old_x, server_x))
\r
5766 // すでに登録されている証明書と完全一致した
\r
5767 if (old_x != NULL)
\r
5775 dlg.DiffWarning = true;
\r
5779 // この証明書は信頼できないのでダイアログボックスを出して確認する
\r
5780 UniStrCpy(dlg.AccountName, sizeof(dlg.AccountName), a->ClientOption->AccountName);
\r
5781 StrCpy(dlg.ServerName, sizeof(dlg.ServerName), a->ClientOption->Hostname);
\r
5783 dlg.old_x = old_x;
\r
5788 CncCheckCert(s, &dlg);
\r
5790 ReleaseSession(s);
\r
5792 if (old_x != NULL)
\r
5797 if (dlg.Ok && dlg.SaveServerCert)
\r
5799 // このサーバー証明書を保存し次回から信頼する
\r
5802 if (a->ServerCert != NULL)
\r
5804 FreeX(a->ServerCert);
\r
5807 a->ServerCert = CloneX(server_x);
\r
5810 CiSaveConfigurationFile(s->Cedar->Client);
\r
5818 if (s == NULL || c == NULL || server_x == NULL)
\r
5823 if (expired != NULL)
\r
5836 if (a->CheckServerCert == false)
\r
5843 if (a->ServerCert != NULL)
\r
5845 old_x = CloneX(a->ServerCert);
\r
5850 if (CheckXDateNow(server_x) == false)
\r
5853 if (old_x != NULL)
\r
5858 if (expired != NULL)
\r
5866 if (old_x != NULL)
\r
5868 if (CompareX(old_x, server_x))
\r
5870 // すでに登録されている証明書と完全一致した
\r
5871 if (old_x != NULL)
\r
5880 if (old_x != NULL)
\r
5888 if (old_x != NULL)
\r
5894 #endif // OS_WIN32
\r
5897 // セキュアデバイスを使用した署名プロシージャ
\r
5898 bool CiSecureSignProc(SESSION *s, CONNECTION *c, SECURE_SIGN *sign)
\r
5900 // Win32 の場合は UI を使用することができる
\r
5901 return CncSecureSignDlg(sign);
\r
5905 // 署名プロシージャ (Win32 用)
\r
5906 bool Win32CiSecureSign(SECURE_SIGN *sign)
\r
5916 random = NewBuf();
\r
5917 WriteBuf(random, sign->Random, SHA1_SIZE);
\r
5921 WINUI_SECURE_BATCH batch[] =
\r
5923 {WINUI_SECURE_READ_CERT, sign->SecurePublicCertName, true, NULL, NULL, NULL, NULL, NULL, NULL},
\r
5924 {WINUI_SECURE_SIGN_WITH_KEY, sign->SecurePrivateKeyName, true, random, NULL, NULL, NULL, NULL, NULL}
\r
5927 if (SecureDeviceWindow(NULL, batch, sizeof(batch) / sizeof(batch[0]),
\r
5928 sign->UseSecureDeviceId, sign->BitmapId) == false)
\r
5931 if (batch[0].OutputX != 0)
\r
5933 FreeX(batch[0].OutputX);
\r
5941 sign->ClientCert = batch[0].OutputX;
\r
5942 Copy(sign->Signature, batch[1].OutputSign, 128);
\r
5950 #endif // OS_WIN32
\r
5953 bool CtDisconnect(CLIENT *c, RPC_CLIENT_CONNECT *connect)
\r
5957 SESSION *s = NULL;
\r
5959 if (c == NULL || connect == NULL)
\r
5964 LockList(c->AccountList);
\r
5968 t.ClientOption = ZeroMalloc(sizeof(CLIENT_OPTION));
\r
5969 UniStrCpy(t.ClientOption->AccountName, sizeof(t.ClientOption->AccountName), connect->AccountName);
\r
5971 r = Search(c->AccountList, &t);
\r
5974 // 指定したアカウントは見つからない
\r
5975 UnlockList(c->AccountList);
\r
5977 Free(t.ClientOption);
\r
5978 CiSetError(c, ERR_ACCOUNT_NOT_FOUND);
\r
5982 Free(t.ClientOption);
\r
5986 if (r->ClientSession == NULL)
\r
5989 CiSetError(c, ERR_ACCOUNT_INACTIVE);
\r
5993 s = r->ClientSession;
\r
5996 r->ClientSession = NULL;
\r
6002 UnlockList(c->AccountList);
\r
6006 // 接続を切断 (切断完了まで待機)
\r
6007 CLog(c, "LC_DISCONNECT", connect->AccountName);
\r
6009 ReleaseSession(s);
\r
6021 bool CtConnect(CLIENT *c, RPC_CLIENT_CONNECT *connect)
\r
6024 RPC_CLIENT_ENUM_VLAN t;
\r
6026 if (c == NULL || connect == NULL)
\r
6031 Lock(c->lockForConnect);
\r
6033 Zero(&t, sizeof(t));
\r
6034 if (CtEnumVLan(c, &t))
\r
6036 if (t.NumItem == 0)
\r
6038 // システムに仮想 LAN カードが 1 枚も無い
\r
6039 if (OS_IS_WINDOWS_NT(GetOsInfo()->OsType) || OS_IS_UNIX(GetOsInfo()->OsType))
\r
6041 // Windows NT 系または Linux 系の場合のみ、自動的に "VPN" という名前の
\r
6042 // 新しい仮想 LAN カードを作成する
\r
6043 RPC_CLIENT_CREATE_VLAN t;
\r
6045 Zero(&t, sizeof(t));
\r
6046 StrCpy(t.DeviceName, sizeof(t.DeviceName), "VPN");
\r
6047 CtCreateVLan(c, &t);
\r
6051 CiFreeClientEnumVLan(&t);
\r
6054 Unlock(c->lockForConnect);
\r
6056 CiNormalizeAccountVLan(c);
\r
6058 LockList(c->AccountList);
\r
6061 bool unix_disabled = false;
\r
6064 t.ClientOption = ZeroMalloc(sizeof(CLIENT_OPTION));
\r
6065 UniStrCpy(t.ClientOption->AccountName, sizeof(t.ClientOption->AccountName), connect->AccountName);
\r
6067 r = Search(c->AccountList, &t);
\r
6070 // 指定したアカウントは見つからない
\r
6071 UnlockList(c->AccountList);
\r
6073 Free(t.ClientOption);
\r
6074 CiSetError(c, ERR_ACCOUNT_NOT_FOUND);
\r
6078 Free(t.ClientOption);
\r
6081 // 仮想 LAN カードを検索する
\r
6082 LockList(c->UnixVLanList);
\r
6086 Zero(&t, sizeof(t));
\r
6087 StrCpy(t.Name, sizeof(t.Name), r->ClientOption->DeviceName);
\r
6089 v = Search(c->UnixVLanList, &t);
\r
6092 UnlockList(c->UnixVLanList);
\r
6093 CiSetError(c, ERR_OBJECT_NOT_FOUND);
\r
6097 unix_disabled = v->Enabled ? false : true;
\r
6099 UnlockList(c->UnixVLanList);
\r
6100 #endif // OS_WIN32
\r
6104 bool already_used = false;
\r
6107 if (r->ClientSession != NULL)
\r
6110 CiSetError(c, ERR_ACCOUNT_ACTIVE);
\r
6112 else if (r->ClientAuth->AuthType == CLIENT_AUTHTYPE_SECURE &&
\r
6113 client->UseSecureDeviceId == 0)
\r
6115 // セキュアデバイスが指定されていない
\r
6116 CiSetError(c, ERR_NO_SECURE_DEVICE_SPECIFIED);
\r
6119 else if (MsIsVLanExists(VLAN_ADAPTER_NAME_TAG, r->ClientOption->DeviceName) == false)
\r
6121 // 仮想 LAN カードが見つからない
\r
6122 CiSetError(c, ERR_VLAN_FOR_ACCOUNT_NOT_FOUND);
\r
6125 else if (MsIsVLanEnabled(r->ClientOption->DeviceName) == false)
\r
6127 // 仮想 LAN カードは無効化されている
\r
6128 CiSetError(c, ERR_VLAN_FOR_ACCOUNT_DISABLED);
\r
6132 else if (unix_disabled)
\r
6134 // 仮想 LAN カードは無効化されている
\r
6135 CiSetError(c, ERR_VLAN_FOR_ACCOUNT_DISABLED);
\r
6138 #endif // OS_WIN32
\r
6141 // 仮想 LAN カードがすでに別のアカウントで使用されているかどうか調べる
\r
6142 for (i = 0;i < LIST_NUM(c->AccountList);i++)
\r
6144 ACCOUNT *a = LIST_DATA(c->AccountList, i);
\r
6147 if (StrCmpi(a->ClientOption->DeviceName,
\r
6148 r->ClientOption->DeviceName) == 0)
\r
6150 if (a->ClientSession != NULL)
\r
6152 already_used = true;
\r
6161 CiSetError(c, ERR_VLAN_FOR_ACCOUNT_USED);
\r
6166 PACKET_ADAPTER *pa = VLanGetPacketAdapter();
\r
6168 if (r->ClientAuth->AuthType == CLIENT_AUTHTYPE_SECURE)
\r
6170 // セキュアデバイス認証のためのプロシージャを登録する
\r
6171 r->ClientAuth->SecureSignProc = CiSecureSignProc;
\r
6175 r->ClientAuth->SecureSignProc = NULL;
\r
6178 if (r->CheckServerCert)
\r
6180 // サーバー証明書確認のためのプロシージャを登録する
\r
6181 r->ClientAuth->CheckCertProc = CiCheckCertProc;
\r
6185 r->ClientAuth->CheckCertProc = NULL;
\r
6188 r->StatusPrinter = CiClientStatusPrinter;
\r
6189 r->LastConnectDateTime = SystemTime64();
\r
6191 CLog(c, "LC_CONNECT", connect->AccountName);
\r
6193 r->ClientSession = NewClientSessionEx(c->Cedar, r->ClientOption, r->ClientAuth, pa, r);
\r
6194 Notify(r->ClientSession, CLIENT_NOTIFY_ACCOUNT_CHANGED);
\r
6203 UnlockList(c->AccountList);
\r
6205 CiSaveConfigurationFile(c);
\r
6211 bool CtGetAccount(CLIENT *c, RPC_CLIENT_GET_ACCOUNT *a)
\r
6214 if (c == NULL || a == NULL)
\r
6219 LockList(c->AccountList);
\r
6224 t.ClientOption = ZeroMalloc(sizeof(CLIENT_OPTION));
\r
6225 UniStrCpy(t.ClientOption->AccountName, sizeof(t.ClientOption->AccountName), a->AccountName);
\r
6227 r = Search(c->AccountList, &t);
\r
6230 // 指定したアカウントは見つからない
\r
6231 UnlockList(c->AccountList);
\r
6233 Free(t.ClientOption);
\r
6234 CiSetError(c, ERR_ACCOUNT_NOT_FOUND);
\r
6238 Free(t.ClientOption);
\r
6242 // クライアントオプションをコピー
\r
6243 if (a->ClientOption != NULL)
\r
6245 Free(a->ClientOption);
\r
6247 a->ClientOption = ZeroMalloc(sizeof(CLIENT_OPTION));
\r
6248 Copy(a->ClientOption, r->ClientOption, sizeof(CLIENT_OPTION));
\r
6251 if (a->ClientAuth != NULL)
\r
6253 CiFreeClientAuth(a->ClientAuth);
\r
6255 a->ClientAuth = CopyClientAuth(r->ClientAuth);
\r
6257 a->StartupAccount = r->StartupAccount;
\r
6259 a->CheckServerCert = r->CheckServerCert;
\r
6260 a->ServerCert = NULL;
\r
6261 if (r->ServerCert != NULL)
\r
6263 a->ServerCert = CloneX(r->ServerCert);
\r
6267 Copy(a->ShortcutKey, r->ShortcutKey, SHA1_SIZE);
\r
6269 a->CreateDateTime = r->CreateDateTime;
\r
6270 a->LastConnectDateTime = r->LastConnectDateTime;
\r
6271 a->UpdateDateTime = r->UpdateDateTime;
\r
6276 UnlockList(c->AccountList);
\r
6282 bool CtRenameAccount(CLIENT *c, RPC_RENAME_ACCOUNT *rename)
\r
6286 if (c == NULL || rename == NULL)
\r
6293 if (UniStrCmp(rename->NewName, rename->OldName) == 0)
\r
6299 LockList(c->AccountList);
\r
6301 ACCOUNT t, *r, *r2;
\r
6303 if (UniStrLen(rename->NewName) == 0)
\r
6306 CiSetError(c, ERR_INVALID_VALUE);
\r
6307 UnlockList(c->AccountList);
\r
6312 t.ClientOption = ZeroMalloc(sizeof(CLIENT_OPTION));
\r
6313 UniStrCpy(t.ClientOption->AccountName, sizeof(t.ClientOption->AccountName), rename->OldName);
\r
6315 r = Search(c->AccountList, &t);
\r
6318 // 指定したアカウントは見つからない
\r
6319 UnlockList(c->AccountList);
\r
6321 Free(t.ClientOption);
\r
6322 CiSetError(c, ERR_ACCOUNT_NOT_FOUND);
\r
6326 Free(t.ClientOption);
\r
6329 t.ClientOption = ZeroMalloc(sizeof(CLIENT_OPTION));
\r
6330 UniStrCpy(t.ClientOption->AccountName, sizeof(t.ClientOption->AccountName), rename->NewName);
\r
6332 r2 = Search(c->AccountList, &t);
\r
6335 // 指定した名前のアカウントはすでに存在する
\r
6336 UnlockList(c->AccountList);
\r
6338 Free(t.ClientOption);
\r
6339 CiSetError(c, ERR_ACCOUNT_ALREADY_EXISTS);
\r
6343 Free(t.ClientOption);
\r
6348 if (r->ClientSession != NULL)
\r
6352 UnlockList(c->AccountList);
\r
6353 CiSetError(c, ERR_ACCOUNT_ACTIVE);
\r
6359 UniStrCpy(r->ClientOption->AccountName, sizeof(r->ClientOption->AccountName),
\r
6362 CLog(c, "LC_RENAME_ACCOUNT", rename->OldName, rename->NewName);
\r
6368 Sort(c->AccountList);
\r
6371 UnlockList(c->AccountList);
\r
6373 CiSaveConfigurationFile(c);
\r
6381 bool CtSetClientConfig(CLIENT *c, CLIENT_CONFIG *o)
\r
6385 if (c == NULL || o == NULL)
\r
6390 if (o->UseKeepConnect)
\r
6392 if (IsEmptyStr(o->KeepConnectHost) ||
\r
6393 o->KeepConnectPort == 0 ||
\r
6394 o->KeepConnectPort >= 65536)
\r
6396 CiSetError(c, ERR_INVALID_PARAMETER);
\r
6403 Copy(&c->Config, o, sizeof(CLIENT_CONFIG));
\r
6408 CiSaveConfigurationFile(c);
\r
6410 // Keep Connect の適用
\r
6414 if (o->UseKeepConnect)
\r
6416 StrCpy(k->ServerName, sizeof(k->ServerName), c->Config.KeepConnectHost);
\r
6417 k->ServerPort = c->Config.KeepConnectPort;
\r
6418 k->Interval = c->Config.KeepConnectInterval * 1000;
\r
6419 k->UdpMode = (c->Config.KeepConnectProtocol == CONNECTION_UDP) ? true : false;
\r
6424 k->Enable = false;
\r
6433 bool CtGetClientConfig(CLIENT *c, CLIENT_CONFIG *o)
\r
6436 if (c == NULL || o == NULL)
\r
6443 Copy(o, &c->Config, sizeof(CLIENT_CONFIG));
\r
6450 // アカウントのスタートアップ属性を解除する
\r
6451 bool CtRemoveStartupAccount(CLIENT *c, RPC_CLIENT_DELETE_ACCOUNT *a)
\r
6455 if (c == NULL || a == NULL)
\r
6462 LockList(c->AccountList);
\r
6467 t.ClientOption = ZeroMalloc(sizeof(CLIENT_OPTION));
\r
6468 UniStrCpy(t.ClientOption->AccountName, sizeof(t.ClientOption->AccountName), a->AccountName);
\r
6470 r = Search(c->AccountList, &t);
\r
6473 // 指定したアカウントは見つからない
\r
6474 UnlockList(c->AccountList);
\r
6476 Free(t.ClientOption);
\r
6477 CiSetError(c, ERR_ACCOUNT_NOT_FOUND);
\r
6481 Free(t.ClientOption);
\r
6485 // スタートアップアカウントを解除する
\r
6487 r->StartupAccount = false;
\r
6491 UnlockList(c->AccountList);
\r
6495 CiSaveConfigurationFile(c);
\r
6502 // アカウントをスタートアップアカウントにする
\r
6503 bool CtSetStartupAccount(CLIENT *c, RPC_CLIENT_DELETE_ACCOUNT *a)
\r
6507 if (c == NULL || a == NULL)
\r
6514 LockList(c->AccountList);
\r
6519 t.ClientOption = ZeroMalloc(sizeof(CLIENT_OPTION));
\r
6520 UniStrCpy(t.ClientOption->AccountName, sizeof(t.ClientOption->AccountName), a->AccountName);
\r
6522 r = Search(c->AccountList, &t);
\r
6525 // 指定したアカウントは見つからない
\r
6526 UnlockList(c->AccountList);
\r
6528 Free(t.ClientOption);
\r
6529 CiSetError(c, ERR_ACCOUNT_NOT_FOUND);
\r
6533 Free(t.ClientOption);
\r
6537 // スタートアップアカウントにする
\r
6539 r->StartupAccount = true;
\r
6543 UnlockList(c->AccountList);
\r
6547 CiSaveConfigurationFile(c);
\r
6555 bool CtDeleteAccount(CLIENT *c, RPC_CLIENT_DELETE_ACCOUNT *a)
\r
6559 if (c == NULL || a == NULL)
\r
6566 LockList(c->AccountList);
\r
6571 t.ClientOption = ZeroMalloc(sizeof(CLIENT_OPTION));
\r
6572 UniStrCpy(t.ClientOption->AccountName, sizeof(t.ClientOption->AccountName), a->AccountName);
\r
6574 r = Search(c->AccountList, &t);
\r
6577 // 指定したアカウントは見つからない
\r
6578 UnlockList(c->AccountList);
\r
6580 Free(t.ClientOption);
\r
6581 CiSetError(c, ERR_ACCOUNT_NOT_FOUND);
\r
6585 Free(t.ClientOption);
\r
6590 if (r->ClientSession != NULL)
\r
6594 UnlockList(c->AccountList);
\r
6595 CiSetError(c, ERR_ACCOUNT_ACTIVE);
\r
6600 // このアカウントをリストから削除する
\r
6601 Delete(c->AccountList, r);
\r
6605 // このアカウントのメモリを解放する
\r
6608 CLog(c, "LC_DELETE_ACCOUNT", a->AccountName);
\r
6612 UnlockList(c->AccountList);
\r
6616 CiSaveConfigurationFile(c);
\r
6624 bool CtEnumAccount(CLIENT *c, RPC_CLIENT_ENUM_ACCOUNT *e)
\r
6627 if (c == NULL || e == NULL)
\r
6632 LockList(c->AccountList);
\r
6636 e->NumItem = LIST_NUM(c->AccountList);
\r
6637 e->Items = ZeroMalloc(sizeof(RPC_CLIENT_ENUM_ACCOUNT_ITEM *) * e->NumItem);
\r
6639 for (i = 0;i < e->NumItem;i++)
\r
6641 ACCOUNT *a = LIST_DATA(c->AccountList, i);
\r
6642 RPC_CLIENT_ENUM_ACCOUNT_ITEM *item = ZeroMalloc(sizeof(RPC_CLIENT_ENUM_ACCOUNT_ITEM));
\r
6643 e->Items[i] = item;
\r
6646 UniStrCpy(item->AccountName, sizeof(item->AccountName), a->ClientOption->AccountName);
\r
6649 StrCpy(item->UserName, sizeof(item->UserName), a->ClientAuth->Username);
\r
6652 StrCpy(item->ServerName, sizeof(item->ServerName), a->ClientOption->Hostname);
\r
6655 item->ProxyType = a->ClientOption->ProxyType;
\r
6658 StrCpy(item->DeviceName, sizeof(item->DeviceName), a->ClientOption->DeviceName);
\r
6661 if (item->ProxyType != PROXY_DIRECT)
\r
6663 StrCpy(item->ProxyName, sizeof(item->ProxyName), a->ClientOption->ProxyName);
\r
6667 item->StartupAccount = a->StartupAccount;
\r
6670 item->Active = (a->ClientSession == NULL ? false : true);
\r
6673 item->Connected = (item->Active == false) ? false : a->ClientSession->ConnectSucceed;
\r
6676 item->Port = a->ClientOption->Port;
\r
6679 StrCpy(item->HubName, sizeof(item->HubName), a->ClientOption->HubName);
\r
6681 item->CreateDateTime = a->CreateDateTime;
\r
6682 item->LastConnectDateTime = a->LastConnectDateTime;
\r
6683 item->UpdateDateTime = a->UpdateDateTime;
\r
6686 UnlockList(c->AccountList);
\r
6692 bool CtSetAccount(CLIENT *c, RPC_CLIENT_CREATE_ACCOUNT *a)
\r
6695 if (c == NULL || a == NULL)
\r
6700 // 既存のアカウントが存在するかどうかチェック
\r
6701 LockList(c->AccountList);
\r
6704 t.ClientOption = ZeroMalloc(sizeof(CLIENT_OPTION));
\r
6705 UniStrCpy(t.ClientOption->AccountName, sizeof(t.ClientOption->AccountName),
\r
6706 a->ClientOption->AccountName);
\r
6708 ret = Search(c->AccountList, &t);
\r
6712 UnlockList(c->AccountList);
\r
6713 Free(t.ClientOption);
\r
6715 CiSetError(c, ERR_ACCOUNT_NOT_FOUND);
\r
6719 Free(t.ClientOption);
\r
6721 if (a->ClientAuth->AuthType == CLIENT_AUTHTYPE_CERT)
\r
6723 if (a->ClientAuth->ClientX == NULL ||
\r
6724 a->ClientAuth->ClientX->is_compatible_bit == false ||
\r
6725 a->ClientAuth->ClientK == NULL)
\r
6728 UnlockList(c->AccountList);
\r
6729 CiSetError(c, ERR_NOT_RSA_1024);
\r
6734 if (a->ServerCert != NULL && a->ServerCert->is_compatible_bit == false)
\r
6737 UnlockList(c->AccountList);
\r
6738 CiSetError(c, ERR_NOT_RSA_1024);
\r
6746 // 現在のバージョンではアカウント動作中でも設定の書き換えは行われる
\r
6747 // (ただし次回接続時まで設定は適用されない)
\r
6748 if (ret->ClientSession != NULL)
\r
6751 Unlock(ret->lock);
\r
6752 UnlockList(c->AccountList);
\r
6754 CiSetError(c, ERR_ACCOUNT_ACTIVE);
\r
6761 CiFreeClientAuth(ret->ClientAuth);
\r
6763 // クライアント認証データのコピー
\r
6764 ret->ClientAuth = CopyClientAuth(a->ClientAuth);
\r
6767 Free(ret->ClientOption);
\r
6769 // クライアントオプションのコピー
\r
6770 ret->ClientOption = ZeroMalloc(sizeof(CLIENT_OPTION));
\r
6771 Copy(ret->ClientOption, a->ClientOption, sizeof(CLIENT_OPTION));
\r
6773 ret->StartupAccount = a->StartupAccount;
\r
6775 ret->CheckServerCert = a->CheckServerCert;
\r
6777 if (a->ServerCert != NULL)
\r
6779 if (ret->ServerCert != NULL)
\r
6781 FreeX(ret->ServerCert);
\r
6783 ret->ServerCert = CloneX(a->ServerCert);
\r
6787 if (ret->ServerCert != NULL)
\r
6789 FreeX(ret->ServerCert);
\r
6791 ret->ServerCert = false;
\r
6794 ret->UpdateDateTime = SystemTime64();
\r
6796 Unlock(ret->lock);
\r
6798 UnlockList(c->AccountList);
\r
6800 CiSaveConfigurationFile(c);
\r
6808 bool CtCreateAccount(CLIENT *c, RPC_CLIENT_CREATE_ACCOUNT *a)
\r
6811 if (c == NULL || a == NULL)
\r
6816 // 既存のアカウントが存在するかどうかチェック
\r
6817 LockList(c->AccountList);
\r
6819 ACCOUNT t, *ret, *new_account;
\r
6820 t.ClientOption = ZeroMalloc(sizeof(CLIENT_OPTION));
\r
6821 UniStrCpy(t.ClientOption->AccountName, sizeof(t.ClientOption->AccountName),
\r
6822 a->ClientOption->AccountName);
\r
6824 ret = Search(c->AccountList, &t);
\r
6828 UnlockList(c->AccountList);
\r
6829 Free(t.ClientOption);
\r
6831 CiSetError(c, ERR_ACCOUNT_ALREADY_EXISTS);
\r
6836 Free(t.ClientOption);
\r
6838 if (UniStrLen(a->ClientOption->AccountName) == 0)
\r
6841 UnlockList(c->AccountList);
\r
6842 CiSetError(c, ERR_INVALID_VALUE);
\r
6846 if (a->ClientAuth->AuthType == CLIENT_AUTHTYPE_CERT)
\r
6848 if (a->ClientAuth->ClientX == NULL ||
\r
6849 a->ClientAuth->ClientX->is_compatible_bit == false ||
\r
6850 a->ClientAuth->ClientK == NULL)
\r
6853 UnlockList(c->AccountList);
\r
6854 CiSetError(c, ERR_NOT_RSA_1024);
\r
6859 if (a->ServerCert != NULL && a->ServerCert->is_compatible_bit == false)
\r
6862 UnlockList(c->AccountList);
\r
6863 CiSetError(c, ERR_NOT_RSA_1024);
\r
6868 new_account = ZeroMalloc(sizeof(ACCOUNT));
\r
6869 new_account->lock = NewLock();
\r
6871 // クライアント認証データのコピー
\r
6872 new_account->ClientAuth = CopyClientAuth(a->ClientAuth);
\r
6874 // クライアントオプションのコピー
\r
6875 new_account->ClientOption = ZeroMalloc(sizeof(CLIENT_OPTION));
\r
6876 Copy(new_account->ClientOption, a->ClientOption, sizeof(CLIENT_OPTION));
\r
6878 new_account->StartupAccount = a->StartupAccount;
\r
6880 new_account->CheckServerCert = a->CheckServerCert;
\r
6881 if (a->ServerCert != NULL)
\r
6883 new_account->ServerCert = CloneX(a->ServerCert);
\r
6887 if (IsZero(a->ShortcutKey, SHA1_SIZE))
\r
6889 Rand(new_account->ShortcutKey, SHA1_SIZE);
\r
6893 Copy(new_account->ShortcutKey, a->ShortcutKey, SHA1_SIZE);
\r
6896 new_account->CreateDateTime = new_account->UpdateDateTime = SystemTime64();
\r
6899 Insert(c->AccountList, new_account);
\r
6901 CLog(c, "LC_NEW_ACCOUNT", a->ClientOption->AccountName);
\r
6903 UnlockList(c->AccountList);
\r
6905 CiNormalizeAccountVLan(c);
\r
6907 CiSaveConfigurationFile(c);
\r
6915 void CiFreeClientGetAccount(RPC_CLIENT_GET_ACCOUNT *a)
\r
6924 if (a->ServerCert != NULL)
\r
6926 FreeX(a->ServerCert);
\r
6928 CiFreeClientAuth(a->ClientAuth);
\r
6929 Free(a->ClientOption);
\r
6933 void CiFreeClientCreateAccount(RPC_CLIENT_CREATE_ACCOUNT *a)
\r
6942 if (a->ServerCert != NULL)
\r
6944 FreeX(a->ServerCert);
\r
6946 CiFreeClientAuth(a->ClientAuth);
\r
6947 Free(a->ClientOption);
\r
6951 bool CtDisableVLan(CLIENT *c, RPC_CLIENT_CREATE_VLAN *vlan)
\r
6956 if (c == NULL || vlan == NULL)
\r
6963 if (GetOsInfo()->OsType == OSTYPE_MACOS_X)
\r
6965 // MacOS X では仮想 LAN カードは増減できない
\r
6966 CiSetError(c, ERR_NOT_SUPPORTED);
\r
6970 // 指定した名前の仮想 LAN カードが 1 つ以上のアカウントによって使用されていない
\r
6973 LockList(c->AccountList);
\r
6975 for (i = 0;i < LIST_NUM(c->AccountList);i++)
\r
6977 ACCOUNT *a = LIST_DATA(c->AccountList, i);
\r
6978 if (StrCmpi(a->ClientOption->DeviceName, vlan->DeviceName) == 0)
\r
6982 if (a->ClientSession != NULL)
\r
6991 UnlockList(c->AccountList);
\r
6993 // 仮想 LAN カードを検索する
\r
6994 LockList(c->UnixVLanList);
\r
6998 Zero(&t, sizeof(t));
\r
6999 StrCpy(t.Name, sizeof(t.Name), vlan->DeviceName);
\r
7001 v = Search(c->UnixVLanList, &t);
\r
7004 UnlockList(c->UnixVLanList);
\r
7005 CiSetError(c, ERR_OBJECT_NOT_FOUND);
\r
7010 v->Enabled = false;
\r
7012 UnlockList(c->UnixVLanList);
\r
7014 CiSaveConfigurationFile(c);
\r
7021 // 指定した名前の仮想 LAN カードが 1 つ以上のアカウントによって使用されていない
\r
7024 LockList(c->AccountList);
\r
7026 for (i = 0;i < LIST_NUM(c->AccountList);i++)
\r
7028 ACCOUNT *a = LIST_DATA(c->AccountList, i);
\r
7029 if (StrCmpi(a->ClientOption->DeviceName, vlan->DeviceName) == 0)
\r
7033 if (a->ClientSession != NULL)
\r
7042 UnlockList(c->AccountList);
\r
7048 CiSetError(c, ERR_VLAN_IS_USED);
\r
7054 // 仮想 LAN カードが存在しているかチェック
\r
7055 if (MsIsVLanExists(VLAN_ADAPTER_NAME_TAG, vlan->DeviceName) == false)
\r
7057 CiSetError(c, ERR_OBJECT_NOT_FOUND);
\r
7063 if (MsIs64BitWindows() && Is32() && MsIsAdmin())
\r
7065 // Windows は 64 bit だがこのコードは 32 bit であるので
\r
7066 // driver_installer を起動して処理を実行する
\r
7067 char tmp[MAX_SIZE];
\r
7069 Format(tmp, sizeof(tmp), "disablevlan %s", vlan->DeviceName);
\r
7071 if (MsExecDriverInstaller(tmp) == false)
\r
7073 CiSetError(c, ERR_VLAN_INSTALL_ERROR);
\r
7081 if (MsDisableVLan(vlan->DeviceName) == false)
\r
7083 CiSetError(c, ERR_VLAN_INSTALL_ERROR);
\r
7093 #endif // OS_WIN32
\r
7098 bool CtEnableVLan(CLIENT *c, RPC_CLIENT_CREATE_VLAN *vlan)
\r
7101 if (c == NULL || vlan == NULL)
\r
7108 if (GetOsInfo()->OsType == OSTYPE_MACOS_X)
\r
7110 // MacOS X では仮想 LAN カードは増減できない
\r
7111 CiSetError(c, ERR_NOT_SUPPORTED);
\r
7115 // 仮想 LAN カードを検索する
\r
7116 LockList(c->UnixVLanList);
\r
7120 Zero(&t, sizeof(t));
\r
7121 StrCpy(t.Name, sizeof(t.Name), vlan->DeviceName);
\r
7123 v = Search(c->UnixVLanList, &t);
\r
7126 UnlockList(c->UnixVLanList);
\r
7127 CiSetError(c, ERR_OBJECT_NOT_FOUND);
\r
7132 v->Enabled = true;
\r
7134 UnlockList(c->UnixVLanList);
\r
7136 CiSaveConfigurationFile(c);
\r
7143 // 仮想 LAN カードが存在しているかチェック
\r
7144 if (MsIsVLanExists(VLAN_ADAPTER_NAME_TAG, vlan->DeviceName) == false)
\r
7146 CiSetError(c, ERR_OBJECT_NOT_FOUND);
\r
7151 if (MsIs64BitWindows() && Is32() && MsIsAdmin())
\r
7153 // Windows は 64 bit だがこのコードは 32 bit であるので
\r
7154 // driver_installer を起動して処理を実行する
\r
7155 char tmp[MAX_SIZE];
\r
7157 Format(tmp, sizeof(tmp), "enablevlan %s", vlan->DeviceName);
\r
7159 if (MsExecDriverInstaller(tmp) == false)
\r
7161 CiSetError(c, ERR_VLAN_INSTALL_ERROR);
\r
7169 if (MsEnableVLan(vlan->DeviceName) == false)
\r
7171 CiSetError(c, ERR_VLAN_INSTALL_ERROR);
\r
7181 #endif // OS_WIN32
\r
7186 bool CtDeleteVLan(CLIENT *c, RPC_CLIENT_CREATE_VLAN *d)
\r
7191 if (c == NULL || d == NULL)
\r
7198 if (GetOsInfo()->OsType == OSTYPE_MACOS_X)
\r
7200 // MacOS X では仮想 LAN カードは増減できない
\r
7201 CiSetError(c, ERR_NOT_SUPPORTED);
\r
7205 // 指定した名前の仮想 LAN カードが 1 つ以上のアカウントによって使用されていない
\r
7208 LockList(c->AccountList);
\r
7210 for (i = 0;i < LIST_NUM(c->AccountList);i++)
\r
7212 ACCOUNT *a = LIST_DATA(c->AccountList, i);
\r
7213 if (StrCmpi(a->ClientOption->DeviceName, d->DeviceName) == 0)
\r
7219 UnlockList(c->AccountList);
\r
7225 CiSetError(c, ERR_VLAN_IS_USED);
\r
7230 // 仮想 LAN カードを検索する
\r
7231 LockList(c->UnixVLanList);
\r
7235 Zero(&t, sizeof(t));
\r
7236 StrCpy(t.Name, sizeof(t.Name), d->DeviceName);
\r
7238 v = Search(c->UnixVLanList, &t);
\r
7241 UnlockList(c->UnixVLanList);
\r
7242 CiSetError(c, ERR_OBJECT_NOT_FOUND);
\r
7247 if (Delete(c->UnixVLanList, v))
\r
7252 CLog(c, "LC_DELETE_VLAN", d->DeviceName);
\r
7254 UnixVLanDelete(d->DeviceName);
\r
7256 UnlockList(c->UnixVLanList);
\r
7258 CiNormalizeAccountVLan(c);
\r
7260 CiSaveConfigurationFile(c);
\r
7267 if (MsIsNt() == false)
\r
7270 CiSetError(c, ERR_NOT_SUPPORTED);
\r
7274 // 仮想 LAN カードが存在しているかチェック
\r
7275 if (MsIsVLanExists(VLAN_ADAPTER_NAME_TAG, d->DeviceName) == false)
\r
7277 CiSetError(c, ERR_OBJECT_NOT_FOUND);
\r
7281 // 指定した名前の仮想 LAN カードが 1 つ以上のアカウントによって使用されていない
\r
7284 LockList(c->AccountList);
\r
7286 for (i = 0;i < LIST_NUM(c->AccountList);i++)
\r
7288 ACCOUNT *a = LIST_DATA(c->AccountList, i);
\r
7289 if (StrCmpi(a->ClientOption->DeviceName, d->DeviceName) == 0)
\r
7295 UnlockList(c->AccountList);
\r
7301 CiSetError(c, ERR_VLAN_IS_USED);
\r
7306 if (MsIs64BitWindows() && Is32() && MsIsAdmin())
\r
7308 // Windows は 64 bit だがこのコードは 32 bit であるので
\r
7309 // driver_installer を起動して処理を実行する
\r
7310 char tmp[MAX_SIZE];
\r
7312 Format(tmp, sizeof(tmp), "uninstvlan %s", d->DeviceName);
\r
7314 if (MsExecDriverInstaller(tmp) == false)
\r
7316 CiSetError(c, ERR_VLAN_INSTALL_ERROR);
\r
7322 // 仮想 LAN カードを直接削除
\r
7323 if (MsUninstallVLan(d->DeviceName) == false)
\r
7325 CiSetError(c, ERR_VLAN_INSTALL_ERROR);
\r
7331 CLog(c, "LC_DELETE_VLAN", d->DeviceName);
\r
7333 CiNormalizeAccountVLan(c);
\r
7339 #endif // OS_WIN32
\r
7343 // 最初の VLAN の名前を取得
\r
7344 char *CiGetFirstVLan(CLIENT *c)
\r
7347 RPC_CLIENT_ENUM_VLAN t;
\r
7354 Zero(&t, sizeof(t));
\r
7355 if (CtEnumVLan(c, &t) == false)
\r
7360 if (t.NumItem >= 1)
\r
7363 char *tmp = t.Items[0]->DeviceName;
\r
7365 for (i = 0;i < t.NumItem;i++)
\r
7367 if (t.Items[i]->Enabled)
\r
7369 tmp = t.Items[i]->DeviceName;
\r
7373 ret = CopyStr(tmp);
\r
7376 CiFreeClientEnumVLan(&t);
\r
7382 bool CtEnumVLan(CLIENT *c, RPC_CLIENT_ENUM_VLAN *e)
\r
7387 if (c == NULL || e == NULL)
\r
7394 LockList(c->UnixVLanList);
\r
7396 e->NumItem = LIST_NUM(c->UnixVLanList);
\r
7397 e->Items = ZeroMalloc(sizeof(RPC_CLIENT_ENUM_VLAN_ITEM *) * e->NumItem);
\r
7399 for (i = 0;i < e->NumItem;i++)
\r
7401 RPC_CLIENT_ENUM_VLAN_ITEM *item;
\r
7404 v = LIST_DATA(c->UnixVLanList, i);
\r
7405 e->Items[i] = ZeroMalloc(sizeof(RPC_CLIENT_ENUM_VLAN_ITEM));
\r
7406 item = e->Items[i];
\r
7408 item->Enabled = v->Enabled;
\r
7409 BinToStr(item->MacAddress, sizeof(item->MacAddress), v->MacAddress, 6);
\r
7410 StrCpy(item->DeviceName, sizeof(item->DeviceName), v->Name);
\r
7411 StrCpy(item->Version, sizeof(item->Version), c->Cedar->VerString);
\r
7414 UnlockList(c->UnixVLanList);
\r
7421 t = MsEnumNetworkAdapters(VLAN_ADAPTER_NAME, "---dummy-string-ut--");
\r
7426 e->Items = ZeroMalloc(0);
\r
7431 e->NumItem = t->NumTokens;
\r
7432 e->Items = ZeroMalloc(sizeof(RPC_CLIENT_ENUM_VLAN_ITEM *) * e->NumItem);
\r
7434 for (i = 0;i < e->NumItem;i++)
\r
7437 RPC_CLIENT_ENUM_VLAN_ITEM *item;
\r
7438 e->Items[i] = ZeroMalloc(sizeof(RPC_CLIENT_ENUM_VLAN_ITEM));
\r
7439 item = e->Items[i];
\r
7441 StrCpy(item->DeviceName, sizeof(item->DeviceName), t->Token[i]);
\r
7442 item->Enabled = MsIsVLanEnabled(item->DeviceName);
\r
7444 tmp = MsGetMacAddress(VLAN_ADAPTER_NAME_TAG, item->DeviceName);
\r
7446 StrCpy(item->MacAddress, sizeof(item->MacAddress), tmp);
\r
7449 tmp = MsGetDriverVersion(VLAN_ADAPTER_NAME_TAG, item->DeviceName);
\r
7451 StrCpy(item->Version, sizeof(item->Version), tmp);
\r
7460 #endif // OS_WIN32
\r
7463 // 仮想 LAN カード列挙体の解放
\r
7464 void CiFreeClientEnumVLan(RPC_CLIENT_ENUM_VLAN *e)
\r
7473 for (i = 0;i < e->NumItem;i++)
\r
7475 Free(e->Items[i]);
\r
7480 // 仮想 LAN カードに関する情報の設定
\r
7481 bool CtSetVLan(CLIENT *c, RPC_CLIENT_SET_VLAN *set)
\r
7484 if (c == NULL || set == NULL)
\r
7491 LockList(c->UnixVLanList);
\r
7494 Zero(&t, sizeof(t));
\r
7495 StrCpy(t.Name, sizeof(t.Name), set->DeviceName);
\r
7497 r = Search(c->UnixVLanList, &t);
\r
7501 CiSetError(c, ERR_VLAN_ALREADY_EXISTS);
\r
7502 UnlockList(c->UnixVLanList);
\r
7506 StrToMac(r->MacAddress, set->MacAddress);
\r
7508 UnlockList(c->UnixVLanList);
\r
7510 CiSaveConfigurationFile(c);
\r
7517 // 指定された名前の仮想 LAN カードが存在するかチェック
\r
7518 if (MsIsVLanExists(VLAN_ADAPTER_NAME_TAG, set->DeviceName) == false)
\r
7521 CiSetError(c, ERR_OBJECT_NOT_FOUND);
\r
7526 MsSetMacAddress(VLAN_ADAPTER_NAME_TAG, set->DeviceName, set->MacAddress);
\r
7532 #endif // OS_WIN32
\r
7535 // 仮想 LAN カードに関する情報の取得
\r
7536 bool CtGetVLan(CLIENT *c, RPC_CLIENT_GET_VLAN *get)
\r
7540 if (c == NULL || get == NULL)
\r
7548 CiSetError(c, ERR_NOT_SUPPORTED);
\r
7553 // 指定された名前の仮想 LAN カードが存在するかチェック
\r
7554 if (MsIsVLanExists(VLAN_ADAPTER_NAME_TAG, get->DeviceName) == false)
\r
7557 CiSetError(c, ERR_OBJECT_NOT_FOUND);
\r
7562 get->Enabled = MsIsVLanEnabled(get->DeviceName);
\r
7565 tmp = MsGetMacAddress(VLAN_ADAPTER_NAME_TAG, get->DeviceName);
\r
7566 StrCpy(get->MacAddress, sizeof(get->MacAddress), tmp);
\r
7570 tmp = MsGetDriverVersion(VLAN_ADAPTER_NAME_TAG, get->DeviceName);
\r
7571 StrCpy(get->Version, sizeof(get->Version), tmp);
\r
7575 tmp = MsGetDriverFileName(VLAN_ADAPTER_NAME_TAG, get->DeviceName);
\r
7576 StrCpy(get->FileName, sizeof(get->FileName), tmp);
\r
7580 tmp = MsGetNetworkAdapterGuid(VLAN_ADAPTER_NAME_TAG, get->DeviceName);
\r
7581 StrCpy(get->Guid, sizeof(get->Guid), tmp);
\r
7586 #endif // OS_WIN32
\r
7589 // 仮想 LAN カードのアップグレード
\r
7590 bool CtUpgradeVLan(CLIENT *c, RPC_CLIENT_CREATE_VLAN *create)
\r
7593 KAKUSHI *k = NULL;
\r
7594 #endif // OS_WIN32
\r
7597 if (c == NULL || create == NULL)
\r
7609 if (MsIsNt() == false)
\r
7612 CiSetError(c, ERR_NOT_SUPPORTED);
\r
7616 // 指定された名前の LAN カードがすでに存在していないかどうかチェックする
\r
7617 if (MsIsVLanExists(VLAN_ADAPTER_NAME_TAG, create->DeviceName) == false)
\r
7620 CiSetError(c, ERR_OBJECT_NOT_FOUND);
\r
7625 if (MsIsVista() == false)
\r
7627 k = InitKakushi();
\r
7631 if (MsIsVista() == false)
\r
7633 // インストールを行う (Windows Vista 以外)
\r
7634 if (MsUpgradeVLan(VLAN_ADAPTER_NAME_TAG,
\r
7635 VLAN_CONNECTION_NAME,
\r
7636 create->DeviceName) == false)
\r
7640 CiSetError(c, ERR_VLAN_INSTALL_ERROR);
\r
7647 // インストールを行う (Windows Vista)
\r
7648 char tmp[MAX_SIZE];
\r
7650 Format(tmp, sizeof(tmp), "upgradevlan %s", create->DeviceName);
\r
7652 if (CncExecDriverInstaller(tmp) == false)
\r
7656 CiSetError(c, ERR_VLAN_INSTALL_ERROR);
\r
7664 CLog(c, "LC_UPDATE_VLAN", create->DeviceName);
\r
7670 #endif // OS_WIN32
\r
7674 bool CtCreateVLan(CLIENT *c, RPC_CLIENT_CREATE_VLAN *create)
\r
7680 KAKUSHI *k = NULL;
\r
7681 #endif // OS_WIN32
\r
7684 if (c == NULL || create == NULL)
\r
7692 if (GetOsInfo()->OsType == OSTYPE_MACOS_X)
\r
7694 // MacOS X では仮想 LAN カードは増減できない
\r
7695 CiSetError(c, ERR_NOT_SUPPORTED);
\r
7699 // 指定された名前が有効かどうかチェックする
\r
7700 if (IsSafeStr(create->DeviceName) == false)
\r
7703 CiSetError(c, ERR_VLAN_INVALID_NAME);
\r
7707 // 指定した名前の LAN カードがすでに存在していないかどうかチェックする
\r
7708 LockList(c->UnixVLanList);
\r
7711 Zero(&t, sizeof(t));
\r
7712 StrCpy(t.Name, sizeof(t.Name), create->DeviceName);
\r
7714 r = Search(c->UnixVLanList, &t);
\r
7718 CiSetError(c, ERR_VLAN_ALREADY_EXISTS);
\r
7719 UnlockList(c->UnixVLanList);
\r
7724 r = ZeroMalloc(sizeof(UNIX_VLAN));
\r
7725 r->Enabled = true;
\r
7726 GenMacAddress(r->MacAddress);
\r
7727 StrCpy(r->Name, sizeof(r->Name), create->DeviceName);
\r
7730 if (UnixVLanCreate(r->Name, r->MacAddress) == false)
\r
7734 CiSetError(c, ERR_VLAN_INSTALL_ERROR);
\r
7735 UnlockList(c->UnixVLanList);
\r
7739 CLog(c, "LC_CREATE_VLAN", create->DeviceName);
\r
7741 Add(c->UnixVLanList, r);
\r
7743 UnlockList(c->UnixVLanList);
\r
7745 CiNormalizeAccountVLan(c);
\r
7748 CiSaveConfigurationFile(c);
\r
7754 if (OS_IS_WINDOWS_9X(GetOsInfo()->OsType))
\r
7756 // Win9x では LAN カードは 1 個しか作成できない
\r
7759 t = MsEnumNetworkAdapters(VLAN_ADAPTER_NAME, "---dummy-string-ut--");
\r
7762 if (t->NumTokens >= 1)
\r
7765 CiSetError(c, ERR_NOT_SUPPORTED);
\r
7772 // 指定された名前が有効かどうかチェックする
\r
7773 if (IsSafeStr(create->DeviceName) == false)
\r
7776 CiSetError(c, ERR_VLAN_INVALID_NAME);
\r
7780 max_len = MsIsNt() ? MAX_DEVICE_NAME_LEN : MAX_DEVICE_NAME_LEN_9X;
\r
7781 if (StrLen(create->DeviceName) > max_len)
\r
7784 CiSetError(c, ERR_VLAN_INVALID_NAME);
\r
7788 // 指定された名前の LAN カードがすでに存在していないかどうかチェックする
\r
7789 if (MsIsVLanExists(VLAN_ADAPTER_NAME_TAG, create->DeviceName))
\r
7792 CiSetError(c, ERR_VLAN_ALREADY_EXISTS);
\r
7798 if (MsIsVista() == false)
\r
7800 k = InitKakushi();
\r
7804 if (MsIsVista() == false)
\r
7806 // インストールを行う (Windows Vista 以外)
\r
7807 if (MsInstallVLan(VLAN_ADAPTER_NAME_TAG, VLAN_CONNECTION_NAME, create->DeviceName) == false)
\r
7811 CiSetError(c, ERR_VLAN_INSTALL_ERROR);
\r
7818 // インストールを行う (Windows Vista)
\r
7819 char tmp[MAX_SIZE];
\r
7821 Format(tmp, sizeof(tmp), "instvlan %s", create->DeviceName);
\r
7823 if (CncExecDriverInstaller(tmp) == false)
\r
7827 CiSetError(c, ERR_VLAN_INSTALL_ERROR);
\r
7835 t = MsEnumNetworkAdapters(VLAN_ADAPTER_NAME, "---dummy-string-ut--");
\r
7836 if (t->NumTokens == 1)
\r
7839 // インストールを行った結果、仮想 LAN カードが 1 つになった場合は
\r
7840 // 既存のすべてのアカウントの仮想 LAN カードをこの仮想 LAN カードにセットする
\r
7841 LockList(c->AccountList);
\r
7843 for (i = 0;i < LIST_NUM(c->AccountList);i++)
\r
7845 ACCOUNT *a = LIST_DATA(c->AccountList, i);
\r
7848 if (a->ClientOption != NULL)
\r
7850 StrCpy(a->ClientOption->DeviceName, sizeof(a->ClientOption->DeviceName), create->DeviceName);
\r
7856 UnlockList(c->AccountList);
\r
7860 CLog(c, "LC_CREATE_VLAN", create->DeviceName);
\r
7862 CiNormalizeAccountVLan(c);
\r
7866 CiSaveConfigurationFile(c);
\r
7868 if (MsIsNt() == false)
\r
7870 if (GetOsInfo()->OsType == OSTYPE_WINDOWS_ME)
\r
7872 // Windows Me の場合は警告表示
\r
7873 MsgBox(NULL, 0x00000040L, _UU("CM_9X_VLAN_ME_MESSAGE"));
\r
7876 ReleaseThread(NewThread(Win9xRebootThread, NULL));
\r
7881 #endif // OS_WIN32
\r
7884 // セキュアデバイス内のオブジェクト列挙
\r
7885 bool CtEnumObjectInSecure(CLIENT *c, RPC_ENUM_OBJECT_IN_SECURE *e)
\r
7889 if (c == NULL || e == NULL)
\r
7895 e->ItemName = ZeroMalloc(sizeof(char *) * e->NumItem);
\r
7896 e->ItemType = ZeroMalloc(sizeof(bool) * e->NumItem);
\r
7898 for (i = 0;i < e->NumItem;i++)
\r
7900 char tmp[MAX_SIZE];
\r
7901 Format(tmp, sizeof(tmp), "Test Object %u", i);
\r
7902 e->ItemName[i] = CopyStr(tmp);
\r
7903 e->ItemType[i] = (i % 2 == 0) ? false : true;
\r
7909 // 使用するセキュアデバイスの取得
\r
7910 bool CtGetUseSecure(CLIENT *c, RPC_USE_SECURE *sec)
\r
7913 if (c == NULL || sec == NULL)
\r
7918 sec->DeviceId = c->UseSecureDeviceId;
\r
7923 // 使用するセキュアデバイスの指定
\r
7924 bool CtUseSecure(CLIENT *c, RPC_USE_SECURE *sec)
\r
7927 if (c == NULL || sec == NULL)
\r
7932 // クライアントマネージャに指定されたデバイスが存在するかどうかチェックしない
\r
7933 /* if (CheckSecureDeviceId(sec->DeviceId))
\r
7935 c->UseSecureDeviceId = sec->DeviceId;
\r
7939 CiSetError(c, ERR_OBJECT_NOT_FOUND);
\r
7943 c->UseSecureDeviceId = sec->DeviceId;
\r
7945 CiSaveConfigurationFile(c);
\r
7951 bool CtEnumSecure(CLIENT *c, RPC_CLIENT_ENUM_SECURE *e)
\r
7956 if (c == NULL || e == NULL)
\r
7961 o = GetSecureDeviceList();
\r
7963 e->NumItem = LIST_NUM(o);
\r
7964 e->Items = ZeroMalloc(sizeof(RPC_CLIENT_ENUM_SECURE_ITEM *) * e->NumItem);
\r
7966 for (i = 0;i < LIST_NUM(o);i++)
\r
7968 RPC_CLIENT_ENUM_SECURE_ITEM *item = ZeroMalloc(sizeof(RPC_CLIENT_ENUM_SECURE_ITEM));
\r
7969 SECURE_DEVICE *s = LIST_DATA(o, i);
\r
7971 item->DeviceId = s->Id;
\r
7972 StrCpy(item->DeviceName, sizeof(item->DeviceName), s->DeviceName);
\r
7973 StrCpy(item->Manufacturer, sizeof(item->Manufacturer), s->Manufacturer);
\r
7974 item->Type = s->Type;
\r
7976 e->Items[i] = item;
\r
7983 void CiFreeClientEnumSecure(RPC_CLIENT_ENUM_SECURE *e)
\r
7992 for (i = 0;i < e->NumItem;i++)
\r
7994 Free(e->Items[i]);
\r
7999 // RPC_GET_ISSUER の解放
\r
8000 void CiFreeGetIssuer(RPC_GET_ISSUER *a)
\r
8008 if (a->issuer_x != NULL)
\r
8010 FreeX(a->issuer_x);
\r
8019 bool CtGetIssuer(CLIENT *c, RPC_GET_ISSUER *a)
\r
8023 if (c == NULL || a == NULL)
\r
8028 x = FindCaSignedX(c->Cedar->CaList, a->x);
\r
8031 CiSetError(c, ERR_OBJECT_NOT_FOUND);;
\r
8047 bool CtGetCa(CLIENT *c, RPC_GET_CA *get)
\r
8052 if (c == NULL || get == NULL)
\r
8057 LockList(c->Cedar->CaList);
\r
8061 for (i = 0;i < LIST_NUM(c->Cedar->CaList);i++)
\r
8063 X *x = LIST_DATA(c->Cedar->CaList, i);
\r
8065 if (POINTER_TO_KEY(x) == get->Key)
\r
8072 UnlockList(c->Cedar->CaList);
\r
8078 CiSetError(c, ERR_OBJECT_NOT_FOUND);
\r
8090 bool CtDeleteCa(CLIENT *c, RPC_CLIENT_DELETE_CA *p)
\r
8094 if (c == NULL || p == NULL)
\r
8099 ret = DeleteCa(c->Cedar, p->Key);
\r
8103 CiSetError(c, ERR_OBJECT_NOT_FOUND);
\r
8106 CiSaveConfigurationFile(c);
\r
8112 bool CtAddCa(CLIENT *c, RPC_CERT *cert)
\r
8115 if (c == NULL || cert == NULL)
\r
8120 if (cert->x->is_compatible_bit == false)
\r
8122 CiSetError(c, ERR_NOT_RSA_1024);
\r
8126 AddCa(c->Cedar, cert->x);
\r
8128 CiSaveConfigurationFile(c);
\r
8134 bool CtEnumCa(CLIENT *c, RPC_CLIENT_ENUM_CA *e)
\r
8137 if (c == NULL || e == NULL)
\r
8142 Zero(e, sizeof(RPC_CLIENT_ENUM_CA));
\r
8144 LockList(c->Cedar->CaList);
\r
8147 e->NumItem = LIST_NUM(c->Cedar->CaList);
\r
8148 e->Items = ZeroMalloc(sizeof(RPC_CLIENT_ENUM_CA_ITEM *) * e->NumItem);
\r
8150 for (i = 0;i < e->NumItem;i++)
\r
8152 X *x = LIST_DATA(c->Cedar->CaList, i);
\r
8153 e->Items[i] = ZeroMalloc(sizeof(RPC_CLIENT_ENUM_CA_ITEM));
\r
8154 GetAllNameFromNameEx(e->Items[i]->SubjectName, sizeof(e->Items[i]->SubjectName), x->subject_name);
\r
8155 GetAllNameFromNameEx(e->Items[i]->IssuerName, sizeof(e->Items[i]->IssuerName), x->issuer_name);
\r
8156 e->Items[i]->Expires = x->notAfter;
\r
8157 e->Items[i]->Key = POINTER_TO_KEY(x);
\r
8160 UnlockList(c->Cedar->CaList);
\r
8166 void CiFreeClientEnumCa(RPC_CLIENT_ENUM_CA *e)
\r
8175 for (i = 0;i < e->NumItem;i++)
\r
8177 RPC_CLIENT_ENUM_CA_ITEM *ca = e->Items[i];
\r
8184 bool CtGetPasswordSetting(CLIENT *c, RPC_CLIENT_PASSWORD_SETTING *a)
\r
8186 UCHAR hash[SHA1_SIZE];
\r
8188 if (c == NULL || a == NULL)
\r
8193 Hash(hash, "", 0, true);
\r
8194 if (Cmp(hash, c->EncryptedPassword, SHA1_SIZE) == 0)
\r
8196 a->IsPasswordPresented = false;
\r
8200 a->IsPasswordPresented = true;
\r
8203 a->PasswordRemoteOnly = c->PasswordRemoteOnly;
\r
8209 bool CtSetPassword(CLIENT *c, RPC_CLIENT_PASSWORD *pass)
\r
8216 if (pass->Password == NULL)
\r
8222 str = pass->Password;
\r
8225 if (StrCmp(str, "********") != 0)
\r
8228 Hash(c->EncryptedPassword, str, StrLen(str), true);
\r
8231 c->PasswordRemoteOnly = pass->PasswordRemoteOnly;
\r
8233 CLog(c, "LC_SET_PASSWORD");
\r
8235 CiSaveConfigurationFile(c);
\r
8240 // クライアントエラーコードの設定
\r
8241 void CiSetError(CLIENT *c, UINT err)
\r
8252 // UNIX 仮想 LAN カード比較関数
\r
8253 int CiCompareUnixVLan(void *p1, void *p2)
\r
8255 UNIX_VLAN *v1, *v2;
\r
8256 if (p1 == NULL || p2 == NULL)
\r
8260 v1 = *(UNIX_VLAN **)p1;
\r
8261 v2 = *(UNIX_VLAN **)p2;
\r
8262 if (v1 == NULL || v2 == NULL)
\r
8267 return StrCmpi(v1->Name, v2->Name);
\r
8270 // 不正な VLAN 名が指定されているアカウントの設定を修正する
\r
8271 void CiNormalizeAccountVLan(CLIENT *c)
\r
8282 name = CiGetFirstVLan(c);
\r
8286 LockList(c->AccountList);
\r
8288 for (i = 0;i < LIST_NUM(c->AccountList);i++)
\r
8290 ACCOUNT *a = LIST_DATA(c->AccountList, i);
\r
8294 if (a->ClientOption != NULL)
\r
8296 if (CiIsVLan(c, a->ClientOption->DeviceName) == false)
\r
8298 StrCpy(a->ClientOption->DeviceName, sizeof(a->ClientOption->DeviceName),
\r
8307 UnlockList(c->AccountList);
\r
8315 CiSaveConfigurationFile(c);
\r
8319 // 指定した名前の仮想 LAN カードが存在しているかどうか調べる
\r
8320 bool CiIsVLan(CLIENT *c, char *name)
\r
8323 if (c == NULL || name == NULL)
\r
8333 t = MsEnumNetworkAdapters(VLAN_ADAPTER_NAME, "---dummy-string-ut--");
\r
8339 for (i = 0;i < t->NumTokens;i++)
\r
8341 if (StrCmpi(t->Token[i], name) == 0)
\r
8358 LockList(c->UnixVLanList);
\r
8360 for (i = 0;i < LIST_NUM(c->UnixVLanList);i++)
\r
8362 v = (UNIX_VLAN *)LIST_DATA(c->UnixVLanList, i);
\r
8363 if (StrCmpi(v->Name, name) == 0)
\r
8369 UnlockList(c->UnixVLanList);
\r
8373 #endif // OS_WIN32
\r
8376 // すべての接続アカウントにおいて、存在しない仮想 LAN カードが指定されている場合で
\r
8377 // 現在の仮想 LAN カードが 1 枚だけの場合は、その仮想 LAN カードに指定しなおす
\r
8378 void CiSetVLanToDefault(CLIENT *c)
\r
8380 char device_name[MAX_SIZE];
\r
8391 t = MsEnumNetworkAdapters(VLAN_ADAPTER_NAME, "---dummy-string-ut--");
\r
8396 if (t->NumTokens != 1)
\r
8401 StrCpy(device_name, sizeof(device_name), t->Token[0]);
\r
8409 LockList(c->UnixVLanList);
\r
8411 if (LIST_NUM(c->UnixVLanList) != 1)
\r
8413 UnlockList(c->UnixVLanList);
\r
8416 v = LIST_DATA(c->UnixVLanList, 0);
\r
8417 StrCpy(device_name, sizeof(device_name), v->Name);
\r
8419 UnlockList(c->UnixVLanList);
\r
8421 #endif // OS_WIN32
\r
8425 LockList(c->AccountList);
\r
8427 for (i = 0;i < LIST_NUM(c->AccountList);i++)
\r
8429 ACCOUNT *a = LIST_DATA(c->AccountList, i);
\r
8433 if (CiIsVLan(c, a->ClientOption->DeviceName) == false)
\r
8435 StrCpy(a->ClientOption->DeviceName, sizeof(a->ClientOption->DeviceName),
\r
8442 UnlockList(c->AccountList);
\r
8447 void CiInitConfiguration(CLIENT *c)
\r
8461 c->AccountList = NewList(CiCompareAccount);
\r
8463 // Unix 版 VLAN リスト
\r
8464 if (OS_IS_UNIX(GetOsInfo()->OsType))
\r
8466 c->UnixVLanList = NewList(CiCompareUnixVLan);
\r
8470 CLog(c, "LC_LOAD_CONFIG_1");
\r
8471 if (CiLoadConfigurationFile(c) == false)
\r
8473 CLog(c, "LC_LOAD_CONFIG_3");
\r
8474 // 設定ファイルが存在しないので初期設定を行う
\r
8476 Hash(c->EncryptedPassword, "", 0, true);
\r
8478 if (OS_IS_WINDOWS(GetOsInfo()->OsType))
\r
8480 // Windows の場合はリモートを禁止
\r
8481 c->Config.AllowRemoteConfig = false;
\r
8485 // UNIX の場合もリモートを禁止
\r
8486 c->Config.AllowRemoteConfig = false;
\r
8488 StrCpy(c->Config.KeepConnectHost, sizeof(c->Config.KeepConnectHost), CLIENT_DEFAULT_KEEPALIVE_HOST);
\r
8489 c->Config.KeepConnectPort = CLIENT_DEFAULT_KEEPALIVE_PORT;
\r
8490 c->Config.KeepConnectProtocol = CONNECTION_UDP;
\r
8491 c->Config.KeepConnectInterval = CLIENT_DEFAULT_KEEPALIVE_INTERVAL;
\r
8492 c->Config.UseKeepConnect = false; // Client ではデフォルトでは接続維持機能を使用しない
\r
8494 c->Eraser = NewEraser(c->Logger, 0);
\r
8498 CLog(c, "LC_LOAD_CONFIG_2");
\r
8501 // 仮想 LAN カードの適切な設定
\r
8502 CiSetVLanToDefault(c);
\r
8506 void CiFreeConfiguration(CLIENT *c)
\r
8516 CiSaveConfigurationFile(c);
\r
8519 FreeCfgRw(c->CfgRw);
\r
8522 for (i = 0;i < LIST_NUM(c->AccountList);i++)
\r
8524 ACCOUNT *a = LIST_DATA(c->AccountList, i);
\r
8528 ReleaseList(c->AccountList);
\r
8530 if (c->UnixVLanList != NULL)
\r
8532 // UNIX 版 VLAN リストの解放
\r
8533 for (i = 0;i < LIST_NUM(c->UnixVLanList);i++)
\r
8535 UNIX_VLAN *v = LIST_DATA(c->UnixVLanList, i);
\r
8538 ReleaseList(c->UnixVLanList);
\r
8540 c->UnixVLanList = NULL;
\r
8549 void CiFreeGetCa(RPC_GET_CA *a)
\r
8561 void CiFreeClientAuth(CLIENT_AUTH *auth)
\r
8569 if (auth->ClientX != NULL)
\r
8571 FreeX(auth->ClientX);
\r
8573 if (auth->ClientK != NULL)
\r
8575 FreeK(auth->ClientK);
\r
8582 void CiFreeAccount(ACCOUNT *a)
\r
8591 DeleteLock(a->lock);
\r
8594 Free(a->ClientOption);
\r
8597 CiFreeClientAuth(a->ClientAuth);
\r
8599 if (a->ServerCert != NULL)
\r
8601 FreeX(a->ServerCert);
\r
8608 int CiCompareAccount(void *p1, void *p2)
\r
8611 if (p1 == NULL || p2 == NULL)
\r
8615 a1 = *(ACCOUNT **)p1;
\r
8616 a2 = *(ACCOUNT **)p2;
\r
8617 if (a1 == NULL || a2 == NULL)
\r
8622 return UniStrCmpi(a1->ClientOption->AccountName, a2->ClientOption->AccountName);
\r
8625 // クライアントコンフィグレーションの読み込み
\r
8626 void CiLoadClientConfig(CLIENT_CONFIG *c, FOLDER *f)
\r
8629 if (c == NULL || f == NULL)
\r
8634 c->UseKeepConnect = CfgGetBool(f, "UseKeepConnect");
\r
8635 CfgGetStr(f, "KeepConnectHost", c->KeepConnectHost, sizeof(c->KeepConnectHost));
\r
8636 c->KeepConnectPort = CfgGetInt(f, "KeepConnectPort");
\r
8637 c->KeepConnectProtocol = CfgGetInt(f, "KeepConnectProtocol");
\r
8638 c->AllowRemoteConfig = CfgGetBool(f, "AllowRemoteConfig");
\r
8639 c->KeepConnectInterval = MAKESURE(CfgGetInt(f, "KeepConnectInterval"), KEEP_INTERVAL_MIN, KEEP_INTERVAL_MAX);
\r
8642 // クライアント認証データの読み込み
\r
8643 CLIENT_AUTH *CiLoadClientAuth(FOLDER *f)
\r
8654 a = ZeroMalloc(sizeof(CLIENT_AUTH));
\r
8656 a->AuthType = CfgGetInt(f, "AuthType");
\r
8657 CfgGetStr(f, "Username", a->Username, sizeof(a->Username));
\r
8659 switch (a->AuthType)
\r
8661 case CLIENT_AUTHTYPE_ANONYMOUS:
\r
8664 case CLIENT_AUTHTYPE_PASSWORD:
\r
8665 CfgGetByte(f, "HashedPassword", a->HashedPassword, SHA1_SIZE);
\r
8668 case CLIENT_AUTHTYPE_PLAIN_PASSWORD:
\r
8669 b = CfgGetBuf(f, "EncryptedPassword");
\r
8672 s = DecryptPassword(b);
\r
8673 StrCpy(a->PlainPassword, sizeof(a->PlainPassword), s);
\r
8679 case CLIENT_AUTHTYPE_CERT:
\r
8680 b = CfgGetBuf(f, "ClientCert");
\r
8683 a->ClientX = BufToX(b, false);
\r
8686 b = CfgGetBuf(f, "ClientKey");
\r
8689 a->ClientK = BufToK(b, true, false, NULL);
\r
8694 case CLIENT_AUTHTYPE_SECURE:
\r
8695 CfgGetStr(f, "SecurePublicCertName", a->SecurePublicCertName, sizeof(a->SecurePublicCertName));
\r
8696 CfgGetStr(f, "SecurePrivateKeyName", a->SecurePrivateKeyName, sizeof(a->SecurePrivateKeyName));
\r
8703 // クライアントオプションの読み込み
\r
8704 CLIENT_OPTION *CiLoadClientOption(FOLDER *f)
\r
8715 o = ZeroMalloc(sizeof(CLIENT_OPTION));
\r
8717 CfgGetUniStr(f, "AccountName", o->AccountName, sizeof(o->AccountName));
\r
8718 CfgGetStr(f, "Hostname", o->Hostname, sizeof(o->Hostname));
\r
8719 o->Port = CfgGetInt(f, "Port");
\r
8720 o->PortUDP = CfgGetInt(f, "PortUDP");
\r
8721 o->ProxyType = CfgGetInt(f, "ProxyType");
\r
8722 CfgGetStr(f, "ProxyName", o->ProxyName, sizeof(o->ProxyName));
\r
8723 o->ProxyPort = CfgGetInt(f, "ProxyPort");
\r
8724 CfgGetStr(f, "ProxyUsername", o->ProxyUsername, sizeof(o->ProxyUsername));
\r
8725 b = CfgGetBuf(f, "ProxyPassword");
\r
8726 s = DecryptPassword(b);
\r
8727 StrCpy(o->ProxyPassword, sizeof(o->ProxyPassword), s);
\r
8730 o->NumRetry = CfgGetInt(f, "NumRetry");
\r
8731 o->RetryInterval = CfgGetInt(f, "RetryInterval");
\r
8732 CfgGetStr(f, "HubName", o->HubName, sizeof(o->HubName));
\r
8733 o->MaxConnection = CfgGetInt(f, "MaxConnection");
\r
8734 o->UseEncrypt = CfgGetBool(f, "UseEncrypt");
\r
8735 o->UseCompress = CfgGetBool(f, "UseCompress");
\r
8736 o->HalfConnection = CfgGetBool(f, "HalfConnection");
\r
8737 o->NoRoutingTracking = CfgGetBool(f, "NoRoutingTracking");
\r
8738 CfgGetStr(f, "DeviceName", o->DeviceName, sizeof(o->DeviceName));
\r
8739 o->AdditionalConnectionInterval = CfgGetInt(f, "AdditionalConnectionInterval");
\r
8740 o->HideStatusWindow = CfgGetBool(f, "HideStatusWindow");
\r
8741 o->HideNicInfoWindow = CfgGetBool(f, "HideNicInfoWindow");
\r
8742 o->ConnectionDisconnectSpan = CfgGetInt(f, "ConnectionDisconnectSpan");
\r
8743 o->RequireMonitorMode = CfgGetBool(f, "RequireMonitorMode");
\r
8744 o->RequireBridgeRoutingMode = CfgGetBool(f, "RequireBridgeRoutingMode");
\r
8745 o->DisableQoS = CfgGetBool(f, "DisableQoS");
\r
8746 o->FromAdminPack = CfgGetBool(f, "FromAdminPack");
\r
8747 o->NoTls1 = CfgGetBool(f, "NoTls1");
\r
8753 ACCOUNT *CiLoadClientAccount(FOLDER *f)
\r
8756 FOLDER *client_option_folder, *client_auth_folder;
\r
8765 client_option_folder = CfgGetFolder(f, "ClientOption");
\r
8767 if (client_option_folder != NULL)
\r
8769 // すでに登録されているアカウント名と一致するかどうか比較する
\r
8772 client_auth_folder = CfgGetFolder(f, "ClientAuth");
\r
8774 if (client_option_folder == NULL || client_auth_folder == NULL)
\r
8779 a = ZeroMalloc(sizeof(ACCOUNT));
\r
8780 a->lock = NewLock();
\r
8782 a->ClientOption = CiLoadClientOption(client_option_folder);
\r
8783 a->ClientAuth = CiLoadClientAuth(client_auth_folder);
\r
8785 a->StartupAccount = CfgGetBool(f, "StartupAccount");
\r
8786 a->CheckServerCert = CfgGetBool(f, "CheckServerCert");
\r
8787 a->CreateDateTime = CfgGetInt64(f, "CreateDateTime");
\r
8788 a->UpdateDateTime = CfgGetInt64(f, "UpdateDateTime");
\r
8789 a->LastConnectDateTime = CfgGetInt64(f, "LastConnectDateTime");
\r
8791 b = CfgGetBuf(f, "ServerCert");
\r
8794 a->ServerCert = BufToX(b, false);
\r
8798 if (CfgGetStr(f, "ShortcutKey", tmp, sizeof(tmp)))
\r
8800 BUF *b = StrToBin(tmp);
\r
8801 if (b->Size == SHA1_SIZE)
\r
8803 Copy(a->ShortcutKey, b->Buf, SHA1_SIZE);
\r
8808 if (IsZero(a->ShortcutKey, SHA1_SIZE))
\r
8810 Rand(a->ShortcutKey, SHA1_SIZE);
\r
8816 // アカウントデータベースの読み込み
\r
8817 void CiLoadAccountDatabase(CLIENT *c, FOLDER *f)
\r
8822 if (c == NULL || f == NULL)
\r
8827 t = CfgEnumFolderToTokenList(f);
\r
8833 for (i = 0;i < t->NumTokens;i++)
\r
8835 FOLDER *ff = CfgGetFolder(f, t->Token[i]);
\r
8839 ACCOUNT *a = CiLoadClientAccount(ff);
\r
8842 Add(c->AccountList, a);
\r
8847 Sort(c->AccountList);
\r
8852 // ルート CA 証明書を読み込む
\r
8853 void CiLoadCACert(CLIENT *c, FOLDER *f)
\r
8858 if (c == NULL || f == NULL)
\r
8863 b = CfgGetBuf(f, "X509");
\r
8869 x = BufToX(b, false);
\r
8871 AddCa(c->Cedar, x);
\r
8878 // ルート CA リストを読み込む
\r
8879 void CiLoadCAList(CLIENT *c, FOLDER *f)
\r
8884 if (c == NULL || f == NULL)
\r
8889 t = CfgEnumFolderToTokenList(f);
\r
8893 LockList(cedar->CaList);
\r
8896 for (i = 0;i < t->NumTokens;i++)
\r
8898 FOLDER *folder = CfgGetFolder(f, t->Token[i]);
\r
8899 CiLoadCACert(c, folder);
\r
8902 UnlockList(cedar->CaList);
\r
8908 void CiLoadVLan(CLIENT *c, FOLDER *f)
\r
8910 char tmp[MAX_SIZE];
\r
8915 if (c == NULL || f == NULL)
\r
8920 if (CfgGetStr(f, "MacAddress", tmp, sizeof(tmp)) == false)
\r
8925 b = StrToBin(tmp);
\r
8937 Copy(addr, b->Buf, 6);
\r
8941 if (IsZero(addr, 6))
\r
8946 v = ZeroMalloc(sizeof(UNIX_VLAN));
\r
8947 Copy(v->MacAddress, addr, 6);
\r
8948 StrCpy(v->Name, sizeof(v->Name), f->Name);
\r
8949 v->Enabled = CfgGetBool(f, "Enabled");
\r
8951 Add(c->UnixVLanList, v);
\r
8954 UnixVLanCreate(v->Name, v->MacAddress);
\r
8959 void CiLoadVLanList(CLIENT *c, FOLDER *f)
\r
8963 if (c == NULL || f == NULL)
\r
8968 t = CfgEnumFolderToTokenList(f);
\r
8970 LockList(c->UnixVLanList);
\r
8973 for (i = 0;i < t->NumTokens;i++)
\r
8975 FOLDER *folder = CfgGetFolder(f, t->Token[i]);
\r
8976 CiLoadVLan(c, folder);
\r
8979 UnlockList(c->UnixVLanList);
\r
8984 // 設定ファイルから設定の読み込み
\r
8985 bool CiReadSettingFromCfg(CLIENT *c, FOLDER *root)
\r
8991 FOLDER *cmsetting;
\r
8992 char user_agent[MAX_SIZE];
\r
8994 if (c == NULL || root == NULL)
\r
8999 // Config と AccountDatabase の両方が無い場合は設定を初期化する
\r
9000 config = CfgGetFolder(root, "Config");
\r
9001 if (config == NULL)
\r
9006 db = CfgGetFolder(root, "AccountDatabase");
\r
9012 cmsetting = CfgGetFolder(root, "ClientManagerSetting");
\r
9014 CiLoadClientConfig(&c->Config, config);
\r
9017 c->Eraser = NewEraser(c->Logger, CfgGetInt64(config, "AutoDeleteCheckDiskFreeSpaceMin"));
\r
9019 if (OS_IS_UNIX(GetOsInfo()->OsType) && GetOsInfo()->OsType != OSTYPE_MACOS_X)
\r
9021 // Unix 版仮想 LAN カード一覧の読み込み (MacOS の場合はしない)
\r
9022 vlan = CfgGetFolder(root, "UnixVLan");
\r
9025 CiLoadVLanList(c, vlan);
\r
9029 if (GetOsInfo()->OsType == OSTYPE_MACOS_X)
\r
9034 // MacOS X の場合は Tap を作成する
\r
9035 if (UnixVLanCreate(CLIENT_MACOS_TAP_NAME, NULL) == false)
\r
9038 CLog(c, "LC_TAP_NOT_FOUND");
\r
9039 Alert("tun/tap driver not found.", NULL);
\r
9043 uv = ZeroMalloc(sizeof(UNIX_VLAN));
\r
9044 uv->Enabled = true;
\r
9045 StrCpy(uv->Name, sizeof(uv->Name), CLIENT_MACOS_TAP_NAME);
\r
9046 Add(c->UnixVLanList, uv);
\r
9050 CiLoadAccountDatabase(c, db);
\r
9052 if (CfgGetByte(root, "EncryptedPassword", c->EncryptedPassword, SHA1_SIZE) == false)
\r
9054 Hash(c->EncryptedPassword, "", 0, true);
\r
9057 c->PasswordRemoteOnly = CfgGetBool(root, "PasswordRemoteOnly");
\r
9058 c->UseSecureDeviceId = CfgGetInt(root, "UseSecureDeviceId");
\r
9060 if (CfgGetStr(root, "UserAgent", user_agent, sizeof(user_agent)))
\r
9062 if (IsEmptyStr(user_agent) == false)
\r
9064 Free(c->Cedar->HttpUserAgent);
\r
9065 c->Cedar->HttpUserAgent = CopyStr(user_agent);
\r
9069 cert = CfgGetFolder(root, "RootCA");
\r
9072 CiLoadCAList(c, cert);
\r
9075 c->DontSavePassword = CfgGetBool(root, "DontSavePassword");
\r
9077 if (cmsetting != NULL)
\r
9079 UINT ostype = GetOsInfo()->OsType;
\r
9081 CM_SETTING *s = c->CmSetting;
\r
9083 if (OS_IS_UNIX(ostype) || OS_IS_WINDOWS_NT(ostype))
\r
9085 s->EasyMode = CfgGetBool(cmsetting, "EasyMode");
\r
9088 s->LockMode = CfgGetBool(cmsetting, "LockMode");
\r
9089 CfgGetByte(cmsetting, "HashedPassword", s->HashedPassword, sizeof(s->HashedPassword));
\r
9096 bool CiLoadConfigurationFile(CLIENT *c)
\r
9107 c->CfgRw = NewCfgRw(&root, CLIENT_CONFIG_FILE_NAME);
\r
9114 ret = CiReadSettingFromCfg(c, root);
\r
9116 CfgDeleteFolder(root);
\r
9121 // CLIENT_CONFIG を書き込む
\r
9122 void CiWriteClientConfig(FOLDER *cc, CLIENT_CONFIG *config)
\r
9125 if (cc == NULL || config == NULL)
\r
9130 CfgAddBool(cc, "UseKeepConnect", config->UseKeepConnect);
\r
9131 CfgAddStr(cc, "KeepConnectHost", config->KeepConnectHost);
\r
9132 CfgAddInt(cc, "KeepConnectPort", config->KeepConnectPort);
\r
9133 CfgAddInt(cc, "KeepConnectProtocol", config->KeepConnectProtocol);
\r
9134 CfgAddBool(cc, "AllowRemoteConfig", config->AllowRemoteConfig);
\r
9135 CfgAddInt(cc, "KeepConnectInterval", config->KeepConnectInterval);
\r
9138 // クライアント認証データを書き込む
\r
9139 void CiWriteClientAuth(FOLDER *f, CLIENT_AUTH *a)
\r
9143 if (f == NULL || a == NULL)
\r
9148 CfgAddInt(f, "AuthType", a->AuthType);
\r
9149 CfgAddStr(f, "Username", a->Username);
\r
9151 switch (a->AuthType)
\r
9153 case CLIENT_AUTHTYPE_ANONYMOUS:
\r
9156 case CLIENT_AUTHTYPE_PASSWORD:
\r
9157 CfgAddByte(f, "HashedPassword", a->HashedPassword, SHA1_SIZE);
\r
9160 case CLIENT_AUTHTYPE_PLAIN_PASSWORD:
\r
9161 b = EncryptPassword(a->PlainPassword);
\r
9162 CfgAddByte(f, "EncryptedPassword", b->Buf, b->Size);
\r
9166 case CLIENT_AUTHTYPE_CERT:
\r
9167 if (a->ClientK != NULL && a->ClientX != NULL)
\r
9169 b = XToBuf(a->ClientX, false);
\r
9170 CfgAddByte(f, "ClientCert", b->Buf, b->Size);
\r
9173 b = KToBuf(a->ClientK, false, NULL);
\r
9174 CfgAddByte(f, "ClientKey", b->Buf, b->Size);
\r
9179 case CLIENT_AUTHTYPE_SECURE:
\r
9180 CfgAddStr(f, "SecurePublicCertName", a->SecurePublicCertName);
\r
9181 CfgAddStr(f, "SecurePrivateKeyName", a->SecurePrivateKeyName);
\r
9186 // クライアントオプションを書き込む
\r
9187 void CiWriteClientOption(FOLDER *f, CLIENT_OPTION *o)
\r
9191 if (f == NULL || o == NULL)
\r
9196 CfgAddUniStr(f, "AccountName", o->AccountName);
\r
9197 CfgAddStr(f, "Hostname", o->Hostname);
\r
9198 CfgAddInt(f, "Port", o->Port);
\r
9199 CfgAddInt(f, "PortUDP", o->PortUDP);
\r
9200 CfgAddInt(f, "ProxyType", o->ProxyType);
\r
9201 CfgAddStr(f, "ProxyName", o->ProxyName);
\r
9202 CfgAddInt(f, "ProxyPort", o->ProxyPort);
\r
9203 CfgAddStr(f, "ProxyUsername", o->ProxyUsername);
\r
9204 b = EncryptPassword(o->ProxyPassword);
\r
9205 CfgAddByte(f, "ProxyPassword", b->Buf, b->Size);
\r
9207 CfgAddInt(f, "NumRetry", o->NumRetry);
\r
9208 CfgAddInt(f, "RetryInterval", o->RetryInterval);
\r
9209 CfgAddStr(f, "HubName", o->HubName);
\r
9210 CfgAddInt(f, "MaxConnection", o->MaxConnection);
\r
9211 CfgAddBool(f, "UseEncrypt", o->UseEncrypt);
\r
9212 CfgAddBool(f, "UseCompress", o->UseCompress);
\r
9213 CfgAddBool(f, "HalfConnection", o->HalfConnection);
\r
9214 CfgAddBool(f, "NoRoutingTracking", o->NoRoutingTracking);
\r
9215 CfgAddStr(f, "DeviceName", o->DeviceName);
\r
9216 CfgAddInt(f, "AdditionalConnectionInterval", o->AdditionalConnectionInterval);
\r
9217 CfgAddBool(f, "HideStatusWindow", o->HideStatusWindow);
\r
9218 CfgAddBool(f, "HideNicInfoWindow", o->HideNicInfoWindow);
\r
9219 CfgAddInt(f, "ConnectionDisconnectSpan", o->ConnectionDisconnectSpan);
\r
9220 CfgAddBool(f, "RequireMonitorMode", o->RequireMonitorMode);
\r
9221 CfgAddBool(f, "RequireBridgeRoutingMode", o->RequireBridgeRoutingMode);
\r
9222 CfgAddBool(f, "DisableQoS", o->DisableQoS);
\r
9223 CfgAddBool(f, "NoTls1", o->NoTls1);
\r
9225 if (o->FromAdminPack)
\r
9227 CfgAddBool(f, "FromAdminPack", o->FromAdminPack);
\r
9232 char *DecryptPassword(BUF *b)
\r
9235 char *key = "EncryptPassword";
\r
9240 return CopyStr("");
\r
9243 str = ZeroMalloc(b->Size + 1);
\r
9244 c = NewCrypt(key, sizeof(key));
\r
9245 Encrypt(c, str, b->Buf, b->Size);
\r
9254 BUF *EncryptPassword(char *password)
\r
9258 char *key = "EncryptPassword";
\r
9262 if (password == NULL)
\r
9267 size = StrLen(password) + 1;
\r
9268 tmp = ZeroMalloc(size);
\r
9270 c = NewCrypt(key, sizeof(key));
\r
9271 Encrypt(c, tmp, password, size - 1);
\r
9275 WriteBuf(b, tmp, size - 1);
\r
9283 void CiWriteAccountData(FOLDER *f, ACCOUNT *a)
\r
9286 if (f == NULL || a == NULL)
\r
9292 CiWriteClientOption(CfgCreateFolder(f, "ClientOption"), a->ClientOption);
\r
9295 CiWriteClientAuth(CfgCreateFolder(f, "ClientAuth"), a->ClientAuth);
\r
9298 CfgAddBool(f, "StartupAccount", a->StartupAccount);
\r
9301 CfgAddBool(f, "CheckServerCert", a->CheckServerCert);
\r
9304 CfgAddInt64(f, "CreateDateTime", a->CreateDateTime);
\r
9305 CfgAddInt64(f, "UpdateDateTime", a->UpdateDateTime);
\r
9306 CfgAddInt64(f, "LastConnectDateTime", a->LastConnectDateTime);
\r
9309 if (a->ServerCert != NULL)
\r
9311 BUF *b = XToBuf(a->ServerCert, false);
\r
9314 CfgAddBuf(f, "ServerCert", b);
\r
9320 if (IsZero(a->ShortcutKey, SHA1_SIZE) == false)
\r
9323 BinToStr(tmp, sizeof(tmp), a->ShortcutKey, SHA1_SIZE);
\r
9324 CfgAddStr(f, "ShortcutKey", tmp);
\r
9328 // アカウントデータベースを書き込む
\r
9329 void CiWriteAccountDatabase(CLIENT *c, FOLDER *f)
\r
9331 char name[MAX_SIZE];
\r
9333 if (c == NULL || f == NULL)
\r
9338 LockList(c->AccountList);
\r
9341 for (i = 0;i < LIST_NUM(c->AccountList);i++)
\r
9343 ACCOUNT *a = LIST_DATA(c->AccountList, i);
\r
9344 Format(name, sizeof(name), "Account%u", i);
\r
9347 CiWriteAccountData(CfgCreateFolder(f, name), a);
\r
9352 UnlockList(c->AccountList);
\r
9356 void CiWriteCACert(CLIENT *c, FOLDER *f, X *x)
\r
9360 if (c == NULL || f == NULL || x == NULL)
\r
9365 b = XToBuf(x, false);
\r
9366 CfgAddBuf(f, "X509", b);
\r
9371 void CiWriteVLan(CLIENT *c, FOLDER *f, UNIX_VLAN *v)
\r
9373 char tmp[MAX_SIZE];
\r
9375 if (c == NULL || f == NULL || v == NULL)
\r
9380 MacToStr(tmp, sizeof(tmp), v->MacAddress);
\r
9381 CfgAddStr(f, "MacAddress", tmp);
\r
9382 CfgAddBool(f, "Enabled", v->Enabled);
\r
9386 void CiWriteVLanList(CLIENT *c, FOLDER *f)
\r
9389 if (c == NULL || f == NULL)
\r
9394 LockList(c->UnixVLanList);
\r
9397 for (i = 0;i < LIST_NUM(c->UnixVLanList);i++)
\r
9399 UNIX_VLAN *v = LIST_DATA(c->UnixVLanList, i);
\r
9400 CiWriteVLan(c, CfgCreateFolder(f, v->Name), v);
\r
9403 UnlockList(c->UnixVLanList);
\r
9407 void CiWriteCAList(CLIENT *c, FOLDER *f)
\r
9411 if (c == NULL || f == NULL)
\r
9418 LockList(cedar->CaList);
\r
9421 for (i = 0;i < LIST_NUM(cedar->CaList);i++)
\r
9423 char tmp[MAX_SIZE];
\r
9424 X *x = LIST_DATA(cedar->CaList, i);
\r
9425 Format(tmp, sizeof(tmp), "Certificate%u", i);
\r
9426 CiWriteCACert(c, CfgCreateFolder(f, tmp), x);
\r
9429 UnlockList(cedar->CaList);
\r
9432 // 現在の設定を ROOT に書き込む
\r
9433 void CiWriteSettingToCfg(CLIENT *c, FOLDER *root)
\r
9436 FOLDER *account_database;
\r
9439 FOLDER *cmsetting;
\r
9441 if (c == NULL || root == NULL)
\r
9446 cmsetting = CfgCreateFolder(root, "ClientManagerSetting");
\r
9449 cc = CfgCreateFolder(root, "Config");
\r
9450 CiWriteClientConfig(cc, &c->Config);
\r
9453 CfgAddInt64(cc, "AutoDeleteCheckDiskFreeSpaceMin", c->Eraser->MinFreeSpace);
\r
9455 // Account Database
\r
9456 account_database = CfgCreateFolder(root, "AccountDatabase");
\r
9457 CiWriteAccountDatabase(c, account_database);
\r
9460 ca = CfgCreateFolder(root, "RootCA");
\r
9461 CiWriteCAList(c, ca);
\r
9464 if (OS_IS_UNIX(GetOsInfo()->OsType) && GetOsInfo()->OsType != OSTYPE_MACOS_X)
\r
9466 vlan = CfgCreateFolder(root, "UnixVLan");
\r
9467 CiWriteVLanList(c, vlan);
\r
9471 CfgAddByte(root, "EncryptedPassword", c->EncryptedPassword, SHA1_SIZE);
\r
9472 CfgAddBool(root, "PasswordRemoteOnly", c->PasswordRemoteOnly);
\r
9474 // UseSecureDeviceId
\r
9475 CfgAddInt(root, "UseSecureDeviceId", c->UseSecureDeviceId);
\r
9477 // DontSavePassword
\r
9478 CfgAddBool(root, "DontSavePassword", c->DontSavePassword);
\r
9481 if (c->Cedar != NULL)
\r
9483 CfgAddStr(root, "UserAgent", c->Cedar->HttpUserAgent);
\r
9486 if (cmsetting != NULL)
\r
9488 CM_SETTING *s = c->CmSetting;
\r
9490 CfgAddBool(cmsetting, "EasyMode", s->EasyMode);
\r
9491 CfgAddBool(cmsetting, "LockMode", s->LockMode);
\r
9493 if (IsZero(s->HashedPassword, sizeof(s->HashedPassword)) == false)
\r
9495 CfgAddByte(cmsetting, "HashedPassword", s->HashedPassword, sizeof(s->HashedPassword));
\r
9501 void CiSaveConfigurationFile(CLIENT *c)
\r
9511 if(c->NoSaveConfig)
\r
9516 root = CfgCreateFolder(NULL, TAG_ROOT);
\r
9517 CiWriteSettingToCfg(c, root);
\r
9519 SaveCfgRw(c->CfgRw, root);
\r
9521 CfgDeleteFolder(root);
\r
9525 bool CtSetCmSetting(CLIENT *c, CM_SETTING *s)
\r
9528 if (c == NULL || s == NULL)
\r
9533 Copy(c->CmSetting, s, sizeof(CM_SETTING));
\r
9535 CiSaveConfigurationFile(c);
\r
9541 bool CtGetCmSetting(CLIENT *c, CM_SETTING *s)
\r
9544 if (c == NULL || s == NULL)
\r
9549 Copy(s, c->CmSetting, sizeof(CM_SETTING));
\r
9555 bool CtGetClientVersion(CLIENT *c, RPC_CLIENT_VERSION *ver)
\r
9563 Zero(ver, sizeof(RPC_CLIENT_VERSION));
\r
9564 StrCpy(ver->ClientProductName, sizeof(ver->ClientProductName), CEDAR_CLIENT_STR);
\r
9565 StrCpy(ver->ClientVersionString, sizeof(ver->ClientVersionString), c->Cedar->VerString);
\r
9566 StrCpy(ver->ClientBuildInfoString, sizeof(ver->ClientBuildInfoString), c->Cedar->BuildInfo);
\r
9567 ver->ClientVerInt = c->Cedar->Version;
\r
9568 ver->ClientBuildInt = c->Cedar->Build;
\r
9571 ver->ProcessId = MsGetProcessId();
\r
9572 #endif // OS_WIN32
\r
9574 ver->OsType = GetOsInfo()->OsType;
\r
9579 // クライアントオブジェクトの作成
\r
9580 CLIENT *CiNewClient()
\r
9582 CLIENT *c = ZeroMalloc(sizeof(CLIENT));
\r
9584 // StartCedarLog();
\r
9586 c->CmSetting = ZeroMalloc(sizeof(CM_SETTING));
\r
9588 c->SockList = NewSockList();
\r
9590 c->lock = NewLock();
\r
9591 c->lockForConnect = NewLock();
\r
9592 c->ref = NewRef();
\r
9594 c->Cedar = NewCedar(NULL, NULL);
\r
9596 c->Cedar->Client = c;
\r
9598 c->NotifyCancelList = NewList(NULL);
\r
9600 Hash(c->EncryptedPassword, "", 0, true);
\r
9603 if(c->NoSaveLog == false)
\r
9605 MakeDir(CLIENT_LOG_DIR_NAME);
\r
9606 c->Logger = NewLog(CLIENT_LOG_DIR_NAME, CLIENT_LOG_PREFIX, LOG_SWITCH_DAY);
\r
9609 CLog(c, "L_LINE");
\r
9610 CLog(c, "LC_START_2", CEDAR_CLIENT_STR, c->Cedar->VerString);
\r
9611 CLog(c, "LC_START_3", c->Cedar->BuildInfo);
\r
9612 CLog(c, "LC_START_1");
\r
9617 wchar_t tmp[MAX_SIZE];
\r
9618 StrToUni(tmp, sizeof(tmp), CEDAR_CLIENT_STR);
\r
9620 InitWinUi(tmp, _SS("DEFAULT_FONT"), _II("DEFAULT_FONT_SIZE"));
\r
9622 #endif // OS_WIN32
\r
9625 CiInitConfiguration(c);
\r
9628 OSSetHighPriority();
\r
9631 // Win9x の場合、すべての仮想 LAN カードの DHCP アドレスを解放する
\r
9632 if (MsIsNt() == false)
\r
9634 Win32ReleaseAllDhcp9x(true);
\r
9636 #endif // OS_WIN32
\r
9638 CiChangeAllVLanMacAddressIfMachineChanged(c);
\r
9644 void CiCleanupClient(CLIENT *c)
\r
9653 CiFreeConfiguration(c);
\r
9658 #endif // OS_WIN32
\r
9660 CLog(c, "LC_END");
\r
9661 CLog(c, "L_LINE");
\r
9662 FreeEraser(c->Eraser);
\r
9663 FreeLog(c->Logger);
\r
9666 ReleaseCedar(c->Cedar);
\r
9668 DeleteLock(c->lockForConnect);
\r
9669 DeleteLock(c->lock);
\r
9671 ReleaseList(c->NotifyCancelList);
\r
9673 FreeSockList(c->SockList);
\r
9675 Free(c->CmSetting);
\r
9680 // Win9x の場合、すべての仮想 LAN カードの DHCP アドレスを解放する
\r
9681 if (MsIsNt() == false)
\r
9683 Win32ReleaseAllDhcp9x(true);
\r
9685 #endif // OS_WIN32
\r
9691 void CtReleaseClient(CLIENT *c)
\r
9699 if (Release(c->ref) == 0)
\r
9701 CiCleanupClient(c);
\r
9705 // クライアントプログラムの動作開始
\r
9706 void CtStartClient()
\r
9710 if (client != NULL)
\r
9720 RegistWindowsFirewallAll();
\r
9724 client = CiNewClient();
\r
9727 CiInitKeep(client);
\r
9730 CiStartRpcServer(client);
\r
9733 CiInitSaver(client);
\r
9736 o = NewListFast(NULL);
\r
9737 LockList(client->AccountList);
\r
9739 for (i = 0;i < LIST_NUM(client->AccountList);i++)
\r
9741 ACCOUNT *a = LIST_DATA(client->AccountList, i);
\r
9744 if (a->StartupAccount)
\r
9746 Add(o, CopyUniStr(a->ClientOption->AccountName));
\r
9752 UnlockList(client->AccountList);
\r
9754 for (i = 0;i < LIST_NUM(o);i++)
\r
9756 wchar_t *s = LIST_DATA(o, i);
\r
9757 RPC_CLIENT_CONNECT c;
\r
9758 Zero(&c, sizeof(c));
\r
9759 UniStrCpy(c.AccountName, sizeof(c.AccountName), s);
\r
9760 CtConnect(client, &c);
\r
9766 // クライアントプログラムの動作終了
\r
9767 void CtStopClient()
\r
9770 ACCOUNT **account_list;
\r
9771 if (client == NULL)
\r
9778 client->Halt = true;
\r
9781 CiStopRpcServer(client);
\r
9783 // クライアント通知サービスを終了
\r
9787 CiFreeKeep(client);
\r
9789 // 接続中のアカウントをすべて切断
\r
9790 LockList(client->AccountList);
\r
9792 num = LIST_NUM(client->AccountList);
\r
9793 account_list = ToArray(client->AccountList);
\r
9795 UnlockList(client->AccountList);
\r
9797 for (i = 0;i < num;i++)
\r
9799 ACCOUNT *a = account_list[i];
\r
9800 SESSION *s = NULL;
\r
9804 if (a->ClientSession != NULL)
\r
9806 s = a->ClientSession;
\r
9815 ReleaseSession(s);
\r
9818 if (a->ClientSession != NULL)
\r
9820 ReleaseSession(a->ClientSession);
\r
9821 a->ClientSession = NULL;
\r
9828 Free(account_list);
\r
9831 CiFreeSaver(client);
\r
9834 CtReleaseClient(client);
\r
9842 OS_INFO *info = GetOsInfo();
\r
9844 if (OS_IS_WINDOWS(info->OsType))
\r
9846 bool ok = IS_CLIENT_SUPPORTED_OS(info->OsType);
\r
9851 "SoftEther UT-VPN Client doesn't support this Windows Operating System.\n"
\r
9852 "SoftEther UT-VPN Client requires Windows 98 SE, Windows Me, Windows 2000, Windows XP, Windows Server 2003 or Greater.\n\n"
\r
9853 "Please contact your system administrator.", "SoftEther UT-VPN Client");
\r
9859 // クライアントオブジェクトの取得
\r
9860 CLIENT *CtGetClient()
\r
9862 if (client == NULL)
\r
9867 AddRef(client->ref);
\r
9873 void CiClientStatusPrinter(SESSION *s, wchar_t *status)
\r
9878 if (s == NULL || status == NULL)
\r
9889 if (UniStrCmpi(status, L"init") == 0)
\r
9891 if (a->StatusWindow == NULL && s->Win32HideConnectWindow == false)
\r
9893 a->StatusWindow = CncStatusPrinterWindowStart(s);
\r
9896 else if (UniStrCmpi(status, L"free") == 0)
\r
9898 if (a->StatusWindow != NULL)
\r
9900 CncStatusPrinterWindowStop(a->StatusWindow);
\r
9901 a->StatusWindow = NULL;
\r
9906 if (a->StatusWindow != NULL)
\r
9908 CncStatusPrinterWindowPrint(a->StatusWindow, status);
\r
9912 UniPrint(L"Status: %s\n", status);
\r
9913 #endif // OS_WIN32
\r