123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910291129122913291429152916291729182919292029212922292329242925292629272928292929302931293229332934293529362937293829392940294129422943294429452946294729482949295029512952295329542955295629572958295929602961296229632964296529662967296829692970297129722973297429752976297729782979298029812982298329842985298629872988298929902991299229932994299529962997299829993000300130023003300430053006300730083009301030113012301330143015301630173018301930203021302230233024302530263027302830293030303130323033303430353036303730383039304030413042304330443045304630473048304930503051305230533054305530563057305830593060306130623063306430653066306730683069307030713072307330743075307630773078307930803081308230833084308530863087308830893090309130923093309430953096309730983099310031013102310331043105310631073108310931103111311231133114311531163117311831193120312131223123312431253126312731283129313031313132313331343135313631373138313931403141314231433144314531463147314831493150315131523153315431553156315731583159316031613162316331643165316631673168316931703171317231733174317531763177317831793180318131823183318431853186318731883189319031913192319331943195319631973198319932003201320232033204320532063207320832093210321132123213321432153216321732183219322032213222322332243225322632273228322932303231323232333234323532363237323832393240324132423243324432453246324732483249325032513252325332543255325632573258325932603261326232633264326532663267326832693270327132723273327432753276327732783279328032813282328332843285328632873288328932903291329232933294329532963297329832993300330133023303330433053306330733083309331033113312331333143315331633173318331933203321332233233324332533263327332833293330333133323333333433353336333733383339334033413342334333443345334633473348334933503351335233533354335533563357335833593360336133623363336433653366336733683369337033713372337333743375337633773378337933803381338233833384338533863387338833893390339133923393339433953396339733983399340034013402340334043405340634073408340934103411341234133414341534163417341834193420342134223423342434253426342734283429343034313432343334343435343634373438343934403441344234433444344534463447344834493450345134523453345434553456345734583459346034613462346334643465346634673468346934703471347234733474347534763477347834793480348134823483348434853486348734883489349034913492349334943495349634973498349935003501350235033504350535063507350835093510351135123513351435153516351735183519352035213522352335243525352635273528352935303531353235333534353535363537353835393540354135423543354435453546354735483549355035513552355335543555355635573558355935603561356235633564356535663567356835693570357135723573357435753576357735783579358035813582358335843585358635873588358935903591359235933594359535963597359835993600360136023603360436053606360736083609361036113612361336143615361636173618361936203621362236233624362536263627362836293630363136323633363436353636363736383639364036413642364336443645364636473648364936503651365236533654365536563657365836593660366136623663366436653666366736683669367036713672367336743675367636773678367936803681368236833684368536863687368836893690369136923693369436953696369736983699370037013702370337043705370637073708370937103711371237133714371537163717371837193720372137223723372437253726372737283729373037313732373337343735373637373738373937403741374237433744374537463747374837493750375137523753375437553756375737583759376037613762376337643765376637673768376937703771377237733774377537763777377837793780378137823783378437853786378737883789379037913792379337943795379637973798379938003801380238033804380538063807380838093810381138123813381438153816381738183819382038213822382338243825382638273828382938303831383238333834383538363837383838393840384138423843384438453846384738483849385038513852385338543855385638573858385938603861386238633864386538663867386838693870387138723873387438753876387738783879388038813882388338843885388638873888388938903891389238933894389538963897389838993900390139023903390439053906390739083909391039113912391339143915391639173918391939203921392239233924392539263927392839293930393139323933393439353936393739383939394039413942394339443945394639473948394939503951395239533954395539563957395839593960396139623963396439653966396739683969397039713972397339743975397639773978397939803981398239833984398539863987398839893990399139923993399439953996399739983999400040014002400340044005400640074008400940104011401240134014401540164017401840194020402140224023402440254026402740284029403040314032403340344035403640374038403940404041404240434044404540464047404840494050405140524053405440554056405740584059406040614062406340644065406640674068406940704071407240734074407540764077407840794080408140824083408440854086408740884089409040914092409340944095409640974098409941004101410241034104410541064107410841094110411141124113411441154116411741184119412041214122412341244125412641274128412941304131413241334134413541364137413841394140414141424143414441454146414741484149415041514152415341544155415641574158415941604161416241634164416541664167416841694170417141724173417441754176417741784179418041814182418341844185418641874188418941904191419241934194419541964197419841994200420142024203420442054206420742084209421042114212421342144215421642174218421942204221422242234224422542264227422842294230423142324233423442354236423742384239424042414242424342444245424642474248424942504251425242534254425542564257425842594260426142624263426442654266426742684269427042714272427342744275427642774278427942804281428242834284428542864287428842894290429142924293429442954296429742984299430043014302430343044305430643074308430943104311431243134314431543164317431843194320432143224323432443254326432743284329433043314332433343344335433643374338433943404341434243434344434543464347434843494350435143524353435443554356435743584359436043614362436343644365436643674368436943704371437243734374437543764377437843794380438143824383438443854386438743884389439043914392439343944395439643974398439944004401440244034404440544064407440844094410441144124413441444154416441744184419442044214422442344244425442644274428442944304431443244334434443544364437443844394440444144424443444444454446444744484449445044514452445344544455445644574458445944604461446244634464446544664467446844694470447144724473447444754476447744784479448044814482448344844485448644874488448944904491449244934494449544964497449844994500450145024503450445054506450745084509451045114512451345144515451645174518451945204521452245234524452545264527452845294530453145324533453445354536453745384539454045414542454345444545454645474548454945504551455245534554455545564557455845594560456145624563456445654566456745684569457045714572457345744575457645774578457945804581458245834584458545864587458845894590459145924593459445954596459745984599460046014602460346044605460646074608460946104611461246134614461546164617461846194620462146224623462446254626462746284629463046314632463346344635463646374638463946404641464246434644464546464647464846494650465146524653465446554656465746584659466046614662466346644665466646674668466946704671467246734674467546764677467846794680468146824683468446854686468746884689469046914692469346944695469646974698469947004701470247034704470547064707470847094710471147124713471447154716471747184719472047214722472347244725472647274728472947304731473247334734473547364737473847394740474147424743474447454746474747484749475047514752475347544755475647574758475947604761476247634764476547664767476847694770477147724773477447754776477747784779478047814782478347844785478647874788478947904791479247934794479547964797479847994800480148024803480448054806480748084809481048114812481348144815481648174818481948204821482248234824482548264827482848294830483148324833483448354836483748384839484048414842484348444845484648474848484948504851485248534854485548564857485848594860486148624863486448654866486748684869487048714872487348744875487648774878487948804881488248834884488548864887488848894890489148924893489448954896489748984899490049014902490349044905490649074908490949104911491249134914491549164917491849194920492149224923492449254926492749284929493049314932493349344935493649374938493949404941494249434944494549464947494849494950495149524953495449554956495749584959496049614962496349644965496649674968496949704971497249734974497549764977497849794980498149824983498449854986498749884989499049914992499349944995499649974998499950005001500250035004500550065007500850095010501150125013501450155016501750185019502050215022502350245025502650275028502950305031503250335034503550365037503850395040504150425043504450455046504750485049505050515052505350545055505650575058505950605061506250635064506550665067506850695070507150725073507450755076507750785079508050815082508350845085508650875088508950905091509250935094509550965097509850995100510151025103510451055106510751085109511051115112511351145115511651175118511951205121512251235124512551265127512851295130513151325133513451355136513751385139514051415142514351445145514651475148514951505151515251535154515551565157515851595160516151625163516451655166516751685169517051715172517351745175517651775178517951805181518251835184518551865187518851895190519151925193519451955196519751985199520052015202520352045205520652075208520952105211521252135214521552165217521852195220522152225223522452255226522752285229523052315232523352345235523652375238523952405241524252435244524552465247524852495250525152525253525452555256525752585259526052615262526352645265526652675268526952705271527252735274527552765277527852795280528152825283528452855286528752885289529052915292529352945295529652975298529953005301530253035304530553065307530853095310531153125313531453155316531753185319532053215322532353245325532653275328532953305331533253335334533553365337533853395340534153425343534453455346534753485349535053515352535353545355535653575358535953605361536253635364536553665367536853695370537153725373537453755376537753785379538053815382538353845385538653875388538953905391539253935394539553965397539853995400540154025403540454055406540754085409541054115412541354145415541654175418541954205421542254235424542554265427542854295430543154325433543454355436543754385439544054415442544354445445544654475448544954505451545254535454545554565457545854595460546154625463546454655466546754685469547054715472547354745475547654775478547954805481548254835484548554865487548854895490549154925493549454955496549754985499550055015502550355045505550655075508550955105511551255135514551555165517551855195520552155225523552455255526552755285529553055315532553355345535553655375538553955405541554255435544554555465547554855495550555155525553555455555556555755585559556055615562556355645565556655675568556955705571557255735574557555765577557855795580558155825583558455855586558755885589559055915592559355945595559655975598559956005601560256035604560556065607560856095610561156125613561456155616561756185619562056215622562356245625562656275628562956305631563256335634563556365637563856395640564156425643564456455646564756485649565056515652565356545655565656575658565956605661566256635664566556665667566856695670567156725673567456755676567756785679568056815682568356845685568656875688568956905691569256935694569556965697569856995700570157025703570457055706570757085709571057115712571357145715571657175718571957205721572257235724572557265727572857295730573157325733573457355736573757385739574057415742574357445745574657475748574957505751575257535754575557565757575857595760576157625763576457655766576757685769577057715772577357745775577657775778577957805781578257835784578557865787578857895790579157925793579457955796579757985799580058015802580358045805580658075808580958105811581258135814581558165817581858195820582158225823582458255826582758285829583058315832583358345835583658375838583958405841584258435844584558465847584858495850585158525853585458555856585758585859586058615862586358645865586658675868586958705871587258735874587558765877587858795880588158825883588458855886588758885889589058915892589358945895589658975898589959005901590259035904590559065907590859095910591159125913591459155916591759185919592059215922592359245925592659275928592959305931593259335934593559365937593859395940594159425943594459455946594759485949595059515952595359545955595659575958595959605961596259635964596559665967596859695970597159725973597459755976597759785979598059815982598359845985598659875988598959905991599259935994599559965997599859996000600160026003600460056006600760086009601060116012601360146015601660176018601960206021602260236024602560266027602860296030603160326033603460356036603760386039604060416042604360446045604660476048604960506051605260536054605560566057605860596060606160626063606460656066606760686069607060716072607360746075607660776078607960806081608260836084608560866087608860896090609160926093609460956096609760986099610061016102610361046105610661076108610961106111611261136114611561166117611861196120612161226123612461256126612761286129613061316132613361346135613661376138613961406141614261436144614561466147614861496150615161526153615461556156615761586159616061616162616361646165616661676168616961706171617261736174617561766177617861796180618161826183618461856186618761886189619061916192619361946195619661976198619962006201620262036204620562066207620862096210621162126213621462156216621762186219622062216222622362246225622662276228622962306231623262336234623562366237623862396240624162426243624462456246624762486249625062516252625362546255625662576258625962606261626262636264626562666267626862696270627162726273627462756276627762786279628062816282628362846285628662876288628962906291629262936294629562966297629862996300630163026303630463056306630763086309631063116312631363146315631663176318631963206321632263236324632563266327632863296330633163326333633463356336633763386339634063416342634363446345634663476348634963506351635263536354635563566357635863596360636163626363636463656366636763686369637063716372637363746375637663776378637963806381638263836384638563866387638863896390639163926393639463956396639763986399640064016402640364046405640664076408640964106411641264136414641564166417641864196420642164226423642464256426642764286429643064316432643364346435643664376438643964406441644264436444644564466447644864496450645164526453645464556456645764586459646064616462646364646465646664676468646964706471647264736474647564766477647864796480648164826483648464856486648764886489649064916492649364946495649664976498649965006501650265036504650565066507650865096510651165126513651465156516651765186519652065216522652365246525652665276528652965306531653265336534653565366537653865396540654165426543654465456546654765486549655065516552655365546555655665576558655965606561656265636564656565666567656865696570657165726573657465756576657765786579658065816582658365846585658665876588658965906591659265936594659565966597659865996600660166026603660466056606660766086609661066116612661366146615661666176618661966206621662266236624662566266627662866296630663166326633663466356636663766386639664066416642664366446645664666476648664966506651665266536654665566566657665866596660666166626663666466656666666766686669667066716672667366746675667666776678667966806681668266836684668566866687668866896690669166926693669466956696669766986699670067016702670367046705670667076708670967106711671267136714671567166717671867196720672167226723672467256726672767286729673067316732673367346735673667376738673967406741674267436744674567466747674867496750675167526753675467556756675767586759676067616762676367646765676667676768676967706771677267736774677567766777677867796780678167826783678467856786678767886789679067916792679367946795679667976798679968006801680268036804680568066807680868096810681168126813681468156816681768186819682068216822682368246825682668276828682968306831683268336834683568366837683868396840684168426843684468456846684768486849685068516852685368546855685668576858685968606861686268636864686568666867686868696870687168726873687468756876687768786879688068816882688368846885688668876888688968906891689268936894689568966897689868996900690169026903690469056906690769086909691069116912691369146915691669176918691969206921692269236924692569266927692869296930693169326933693469356936693769386939694069416942694369446945694669476948694969506951695269536954695569566957695869596960696169626963696469656966696769686969697069716972697369746975697669776978697969806981698269836984698569866987698869896990699169926993699469956996699769986999700070017002700370047005700670077008700970107011701270137014701570167017701870197020702170227023702470257026702770287029703070317032703370347035703670377038703970407041704270437044704570467047704870497050705170527053705470557056705770587059706070617062706370647065706670677068706970707071707270737074707570767077707870797080708170827083708470857086708770887089709070917092709370947095709670977098709971007101710271037104710571067107710871097110711171127113711471157116711771187119712071217122712371247125712671277128712971307131713271337134713571367137713871397140714171427143714471457146714771487149715071517152715371547155715671577158715971607161716271637164716571667167716871697170717171727173717471757176717771787179718071817182718371847185718671877188718971907191719271937194719571967197719871997200720172027203720472057206720772087209721072117212721372147215721672177218721972207221722272237224722572267227722872297230723172327233723472357236723772387239724072417242724372447245724672477248724972507251725272537254725572567257725872597260726172627263726472657266726772687269727072717272727372747275727672777278727972807281728272837284728572867287728872897290729172927293729472957296729772987299730073017302730373047305730673077308730973107311731273137314731573167317731873197320732173227323732473257326732773287329733073317332733373347335733673377338733973407341734273437344734573467347734873497350735173527353735473557356735773587359736073617362736373647365736673677368736973707371737273737374737573767377737873797380738173827383738473857386738773887389739073917392739373947395739673977398739974007401740274037404740574067407740874097410741174127413741474157416741774187419742074217422742374247425742674277428742974307431743274337434743574367437743874397440744174427443744474457446744774487449745074517452745374547455745674577458745974607461746274637464746574667467746874697470747174727473747474757476747774787479748074817482748374847485748674877488748974907491749274937494749574967497749874997500750175027503750475057506750775087509751075117512751375147515751675177518751975207521752275237524752575267527752875297530753175327533753475357536753775387539754075417542754375447545754675477548754975507551755275537554755575567557755875597560756175627563756475657566756775687569757075717572757375747575757675777578757975807581758275837584758575867587758875897590759175927593759475957596759775987599760076017602760376047605760676077608760976107611761276137614761576167617761876197620762176227623762476257626762776287629763076317632763376347635763676377638763976407641764276437644764576467647764876497650765176527653765476557656765776587659766076617662766376647665766676677668766976707671767276737674767576767677767876797680768176827683768476857686768776887689769076917692769376947695769676977698769977007701770277037704770577067707770877097710771177127713771477157716771777187719772077217722772377247725772677277728772977307731773277337734773577367737773877397740774177427743774477457746774777487749775077517752775377547755775677577758775977607761776277637764776577667767776877697770777177727773777477757776777777787779778077817782778377847785778677877788778977907791779277937794779577967797779877997800780178027803780478057806780778087809781078117812781378147815781678177818781978207821782278237824782578267827782878297830783178327833783478357836783778387839784078417842784378447845784678477848784978507851785278537854785578567857785878597860786178627863786478657866786778687869787078717872787378747875787678777878787978807881788278837884788578867887788878897890789178927893789478957896789778987899790079017902790379047905790679077908790979107911791279137914791579167917791879197920792179227923792479257926792779287929793079317932793379347935793679377938793979407941794279437944794579467947794879497950795179527953795479557956795779587959796079617962796379647965796679677968796979707971797279737974797579767977797879797980798179827983798479857986798779887989799079917992799379947995799679977998799980008001800280038004800580068007800880098010801180128013801480158016801780188019802080218022802380248025802680278028802980308031803280338034803580368037803880398040804180428043804480458046804780488049805080518052805380548055805680578058805980608061806280638064806580668067806880698070807180728073807480758076807780788079808080818082808380848085808680878088808980908091809280938094809580968097809880998100810181028103810481058106810781088109811081118112811381148115811681178118811981208121812281238124812581268127812881298130813181328133813481358136813781388139814081418142814381448145814681478148814981508151815281538154815581568157815881598160816181628163816481658166816781688169817081718172817381748175817681778178817981808181818281838184818581868187818881898190819181928193819481958196819781988199820082018202820382048205820682078208820982108211821282138214821582168217821882198220822182228223822482258226822782288229823082318232823382348235823682378238823982408241824282438244824582468247824882498250825182528253825482558256825782588259826082618262826382648265826682678268826982708271827282738274827582768277827882798280828182828283828482858286828782888289829082918292829382948295829682978298829983008301830283038304830583068307830883098310831183128313831483158316831783188319832083218322832383248325832683278328832983308331833283338334833583368337833883398340834183428343834483458346834783488349835083518352835383548355835683578358835983608361836283638364836583668367836883698370837183728373837483758376837783788379838083818382838383848385838683878388838983908391839283938394839583968397839883998400840184028403840484058406840784088409841084118412841384148415841684178418841984208421842284238424842584268427842884298430843184328433843484358436843784388439844084418442844384448445844684478448844984508451845284538454845584568457845884598460846184628463846484658466846784688469847084718472847384748475847684778478847984808481848284838484848584868487848884898490849184928493849484958496849784988499850085018502850385048505850685078508850985108511851285138514851585168517851885198520852185228523852485258526852785288529853085318532853385348535853685378538853985408541854285438544854585468547854885498550855185528553855485558556855785588559856085618562856385648565856685678568856985708571857285738574857585768577857885798580858185828583858485858586858785888589859085918592859385948595859685978598859986008601860286038604860586068607860886098610861186128613861486158616861786188619862086218622862386248625862686278628862986308631863286338634863586368637863886398640864186428643864486458646864786488649865086518652865386548655865686578658865986608661866286638664866586668667866886698670867186728673867486758676867786788679868086818682868386848685868686878688868986908691869286938694869586968697869886998700870187028703870487058706870787088709871087118712871387148715871687178718871987208721872287238724872587268727872887298730873187328733873487358736873787388739874087418742874387448745874687478748874987508751875287538754875587568757875887598760876187628763876487658766876787688769877087718772877387748775877687778778877987808781878287838784878587868787878887898790879187928793879487958796879787988799880088018802880388048805880688078808880988108811881288138814881588168817881888198820882188228823882488258826882788288829883088318832883388348835883688378838883988408841884288438844884588468847884888498850885188528853885488558856885788588859886088618862886388648865886688678868886988708871887288738874887588768877887888798880888188828883888488858886888788888889889088918892889388948895889688978898889989008901890289038904890589068907890889098910891189128913891489158916891789188919892089218922892389248925892689278928892989308931893289338934893589368937893889398940894189428943894489458946894789488949895089518952895389548955895689578958895989608961896289638964896589668967896889698970897189728973897489758976897789788979898089818982898389848985898689878988898989908991899289938994899589968997899889999000900190029003900490059006900790089009901090119012901390149015901690179018901990209021902290239024902590269027902890299030903190329033903490359036903790389039904090419042904390449045904690479048904990509051905290539054905590569057905890599060906190629063906490659066906790689069907090719072907390749075907690779078907990809081908290839084908590869087908890899090909190929093909490959096909790989099910091019102910391049105910691079108910991109111911291139114911591169117911891199120912191229123912491259126912791289129913091319132913391349135913691379138913991409141914291439144914591469147914891499150915191529153915491559156915791589159916091619162916391649165916691679168916991709171917291739174917591769177917891799180918191829183918491859186918791889189919091919192919391949195919691979198919992009201920292039204920592069207920892099210921192129213921492159216921792189219922092219222922392249225922692279228922992309231923292339234923592369237923892399240924192429243924492459246924792489249925092519252925392549255925692579258925992609261926292639264926592669267926892699270927192729273927492759276927792789279928092819282928392849285928692879288928992909291929292939294929592969297929892999300930193029303930493059306930793089309931093119312931393149315931693179318931993209321932293239324932593269327932893299330933193329333933493359336933793389339934093419342934393449345934693479348934993509351935293539354935593569357935893599360936193629363936493659366936793689369937093719372937393749375937693779378937993809381938293839384938593869387938893899390939193929393939493959396939793989399940094019402940394049405940694079408940994109411941294139414941594169417941894199420942194229423942494259426942794289429943094319432943394349435943694379438943994409441944294439444944594469447944894499450945194529453945494559456945794589459946094619462946394649465946694679468946994709471947294739474947594769477947894799480948194829483948494859486948794889489949094919492949394949495949694979498949995009501950295039504950595069507950895099510951195129513951495159516951795189519952095219522952395249525952695279528952995309531953295339534953595369537953895399540954195429543954495459546954795489549955095519552955395549555955695579558955995609561956295639564956595669567956895699570957195729573957495759576957795789579958095819582958395849585958695879588958995909591959295939594959595969597959895999600960196029603960496059606960796089609961096119612961396149615961696179618961996209621962296239624962596269627962896299630963196329633963496359636963796389639964096419642964396449645964696479648964996509651965296539654965596569657965896599660966196629663966496659666966796689669967096719672967396749675967696779678967996809681968296839684968596869687968896899690969196929693969496959696969796989699970097019702970397049705970697079708970997109711971297139714971597169717971897199720972197229723972497259726972797289729973097319732973397349735973697379738973997409741974297439744974597469747974897499750975197529753975497559756975797589759976097619762976397649765976697679768976997709771977297739774977597769777977897799780978197829783978497859786978797889789979097919792979397949795979697979798979998009801980298039804980598069807980898099810981198129813981498159816981798189819982098219822982398249825982698279828982998309831983298339834983598369837983898399840984198429843984498459846984798489849985098519852985398549855985698579858985998609861986298639864986598669867986898699870987198729873987498759876987798789879988098819882988398849885988698879888988998909891989298939894989598969897989898999900990199029903990499059906990799089909991099119912991399149915991699179918991999209921992299239924992599269927992899299930993199329933993499359936993799389939994099419942994399449945994699479948994999509951995299539954995599569957995899599960996199629963996499659966996799689969997099719972997399749975997699779978997999809981998299839984998599869987998899899990999199929993999499959996999799989999100001000110002100031000410005100061000710008100091001010011100121001310014100151001610017100181001910020100211002210023100241002510026100271002810029100301003110032100331003410035100361003710038100391004010041100421004310044100451004610047100481004910050100511005210053100541005510056100571005810059100601006110062100631006410065100661006710068100691007010071100721007310074100751007610077100781007910080100811008210083100841008510086100871008810089100901009110092100931009410095100961009710098100991010010101101021010310104101051010610107101081010910110101111011210113101141011510116101171011810119101201012110122101231012410125101261012710128101291013010131101321013310134101351013610137101381013910140101411014210143101441014510146101471014810149101501015110152101531015410155101561015710158101591016010161101621016310164101651016610167101681016910170101711017210173101741017510176101771017810179101801018110182101831018410185101861018710188101891019010191101921019310194101951019610197101981019910200102011020210203102041020510206102071020810209102101021110212102131021410215102161021710218102191022010221102221022310224102251022610227102281022910230102311023210233102341023510236102371023810239102401024110242102431024410245102461024710248102491025010251102521025310254102551025610257102581025910260102611026210263102641026510266102671026810269102701027110272102731027410275102761027710278102791028010281102821028310284102851028610287102881028910290102911029210293102941029510296102971029810299103001030110302103031030410305103061030710308103091031010311103121031310314103151031610317103181031910320103211032210323103241032510326103271032810329103301033110332103331033410335103361033710338103391034010341103421034310344103451034610347103481034910350103511035210353103541035510356103571035810359103601036110362103631036410365103661036710368103691037010371103721037310374103751037610377103781037910380103811038210383103841038510386103871038810389103901039110392103931039410395103961039710398103991040010401104021040310404104051040610407104081040910410104111041210413104141041510416104171041810419104201042110422104231042410425104261042710428104291043010431104321043310434104351043610437104381043910440104411044210443104441044510446104471044810449104501045110452104531045410455104561045710458104591046010461104621046310464104651046610467104681046910470104711047210473104741047510476104771047810479104801048110482104831048410485104861048710488104891049010491104921049310494104951049610497104981049910500105011050210503105041050510506105071050810509105101051110512105131051410515105161051710518105191052010521105221052310524105251052610527105281052910530105311053210533105341053510536105371053810539105401054110542105431054410545105461054710548105491055010551105521055310554105551055610557105581055910560105611056210563105641056510566105671056810569105701057110572105731057410575105761057710578105791058010581105821058310584105851058610587105881058910590105911059210593105941059510596105971059810599106001060110602106031060410605106061060710608106091061010611106121061310614106151061610617106181061910620106211062210623106241062510626106271062810629106301063110632106331063410635106361063710638106391064010641106421064310644106451064610647106481064910650106511065210653106541065510656106571065810659106601066110662106631066410665106661066710668106691067010671106721067310674106751067610677106781067910680106811068210683106841068510686106871068810689106901069110692106931069410695106961069710698106991070010701107021070310704107051070610707107081070910710107111071210713107141071510716107171071810719107201072110722107231072410725107261072710728107291073010731107321073310734107351073610737107381073910740107411074210743107441074510746107471074810749107501075110752107531075410755107561075710758107591076010761107621076310764107651076610767107681076910770107711077210773107741077510776107771077810779107801078110782107831078410785107861078710788107891079010791107921079310794107951079610797107981079910800108011080210803108041080510806108071080810809108101081110812108131081410815108161081710818108191082010821108221082310824108251082610827108281082910830108311083210833108341083510836108371083810839108401084110842108431084410845108461084710848108491085010851108521085310854108551085610857108581085910860108611086210863108641086510866108671086810869108701087110872108731087410875108761087710878108791088010881108821088310884108851088610887108881088910890108911089210893108941089510896108971089810899109001090110902109031090410905109061090710908109091091010911109121091310914109151091610917109181091910920109211092210923109241092510926109271092810929109301093110932109331093410935109361093710938109391094010941109421094310944109451094610947109481094910950109511095210953109541095510956109571095810959109601096110962109631096410965109661096710968109691097010971109721097310974109751097610977109781097910980109811098210983109841098510986109871098810989109901099110992109931099410995109961099710998109991100011001110021100311004110051100611007110081100911010110111101211013110141101511016110171101811019110201102111022110231102411025110261102711028110291103011031110321103311034110351103611037110381103911040110411104211043110441104511046110471104811049110501105111052110531105411055110561105711058110591106011061110621106311064110651106611067110681106911070110711107211073110741107511076110771107811079110801108111082110831108411085110861108711088 |
- // SoftEther VPN Source Code
- // Cedar Communication Module
- //
- // SoftEther VPN Server, Client and Bridge are free software under GPLv2.
- //
- // Copyright (c) 2012-2014 Daiyuu Nobori.
- // Copyright (c) 2012-2014 SoftEther VPN Project, University of Tsukuba, Japan.
- // Copyright (c) 2012-2014 SoftEther Corporation.
- //
- // All Rights Reserved.
- //
- // http://www.softether.org/
- //
- // Author: Daiyuu Nobori
- // Contributors:
- // - nattoheaven (https://github.com/nattoheaven)
- // Comments: Tetsuo Sugiyama, Ph.D.
- //
- // This program is free software; you can redistribute it and/or
- // modify it under the terms of the GNU General Public License
- // version 2 as published by the Free Software Foundation.
- //
- // This program is distributed in the hope that it will be useful,
- // but WITHOUT ANY WARRANTY; without even the implied warranty of
- // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- // GNU General Public License for more details.
- //
- // You should have received a copy of the GNU General Public License version 2
- // along with this program; if not, write to the Free Software
- // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- //
- // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
- // IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
- // CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
- // TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
- // SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- //
- // THE LICENSE AGREEMENT IS ATTACHED ON THE SOURCE-CODE PACKAGE
- // AS "LICENSE.TXT" FILE. READ THE TEXT FILE IN ADVANCE TO USE THE SOFTWARE.
- //
- //
- // THIS SOFTWARE IS DEVELOPED IN JAPAN, AND DISTRIBUTED FROM JAPAN,
- // UNDER JAPANESE LAWS. YOU MUST AGREE IN ADVANCE TO USE, COPY, MODIFY,
- // MERGE, PUBLISH, DISTRIBUTE, SUBLICENSE, AND/OR SELL COPIES OF THIS
- // SOFTWARE, THAT ANY JURIDICAL DISPUTES WHICH ARE CONCERNED TO THIS
- // SOFTWARE OR ITS CONTENTS, AGAINST US (SOFTETHER PROJECT, SOFTETHER
- // CORPORATION, DAIYUU NOBORI OR OTHER SUPPLIERS), OR ANY JURIDICAL
- // DISPUTES AGAINST US WHICH ARE CAUSED BY ANY KIND OF USING, COPYING,
- // MODIFYING, MERGING, PUBLISHING, DISTRIBUTING, SUBLICENSING, AND/OR
- // SELLING COPIES OF THIS SOFTWARE SHALL BE REGARDED AS BE CONSTRUED AND
- // CONTROLLED BY JAPANESE LAWS, AND YOU MUST FURTHER CONSENT TO
- // EXCLUSIVE JURISDICTION AND VENUE IN THE COURTS SITTING IN TOKYO,
- // JAPAN. YOU MUST WAIVE ALL DEFENSES OF LACK OF PERSONAL JURISDICTION
- // AND FORUM NON CONVENIENS. PROCESS MAY BE SERVED ON EITHER PARTY IN
- // THE MANNER AUTHORIZED BY APPLICABLE LAW OR COURT RULE.
- //
- // USE ONLY IN JAPAN. DO NOT USE IT IN OTHER COUNTRIES. IMPORTING THIS
- // SOFTWARE INTO OTHER COUNTRIES IS AT YOUR OWN RISK. SOME COUNTRIES
- // PROHIBIT ENCRYPTED COMMUNICATIONS. USING THIS SOFTWARE IN OTHER
- // COUNTRIES MIGHT BE RESTRICTED.
- //
- //
- // SOURCE CODE CONTRIBUTION
- // ------------------------
- //
- // Your contribution to SoftEther VPN Project is much appreciated.
- // Please send patches to us through GitHub.
- // Read the SoftEther VPN Patch Acceptance Policy in advance:
- // http://www.softether.org/5-download/src/9.patch
- //
- //
- // DEAR SECURITY EXPERTS
- // ---------------------
- //
- // If you find a bug or a security vulnerability please kindly inform us
- // about the problem immediately so that we can fix the security problem
- // to protect a lot of users around the world as soon as possible.
- //
- // Our e-mail address for security reports is:
- // softether-vpn-security [at] softether.org
- //
- // Please note that the above e-mail address is not a technical support
- // inquiry address. If you need technical assistance, please visit
- // http://www.softether.org/ and ask your question on the users forum.
- //
- // Thank you for your cooperation.
- //
- //
- // NO MEMORY OR RESOURCE LEAKS
- // ---------------------------
- //
- // The memory-leaks and resource-leaks verification under the stress
- // test has been passed before release this source code.
- // Client.c
- // Client Manager
- #include "CedarPch.h"
- static CLIENT *client = NULL;
- static LISTENER *cn_listener = NULL;
- static LOCK *cn_listener_lock = NULL;
- static UINT64 cn_next_allow = 0;
- static LOCK *ci_active_sessions_lock = NULL;
- static UINT ci_num_active_sessions = 0;
- // In Windows 8 or later, change unreasonable setting of WCM to ensure normal VPN communication
- void CiDisableWcmNetworkMinimize(CLIENT *c)
- {
- #ifdef OS_WIN32
- // Validate arguments
- if (c == NULL)
- {
- return;
- }
- if (c->Config.NoChangeWcmNetworkSettingOnWindows8)
- {
- return;
- }
- MsDisableWcmNetworkMinimize();
- #endif // OS_WIN32
- }
- // Compare RPC_CLIENT_ENUM_ACCOUNT_ITEM items by last connected date (Reverse)
- int CiCompareClientAccountEnumItemByLastConnectDateTime(void *p1, void *p2)
- {
- RPC_CLIENT_ENUM_ACCOUNT_ITEM *a1, *a2;
- if (p1 == NULL || p2 == NULL)
- {
- return 0;
- }
- a1 = *(RPC_CLIENT_ENUM_ACCOUNT_ITEM **)p1;
- a2 = *(RPC_CLIENT_ENUM_ACCOUNT_ITEM **)p2;
- if (a1 == NULL || a2 == NULL)
- {
- return 0;
- }
- if (a1->LastConnectDateTime > a2->LastConnectDateTime)
- {
- return -1;
- }
- else if (a1->LastConnectDateTime < a2->LastConnectDateTime)
- {
- return 1;
- }
- return 0;
- }
- // If machine changed, reshuffle MAC address for all virtual NIC
- void CiChangeAllVLanMacAddressIfMachineChanged(CLIENT *c)
- {
- UCHAR current_hash_new[SHA1_SIZE];
- UCHAR current_hash[SHA1_SIZE];
- UCHAR current_hash_old[SHA1_SIZE];
- UCHAR saved_hash[SHA1_SIZE];
- // Validate arguments
- if (c == NULL)
- {
- return;
- }
- #ifdef OS_WIN32
- if (MsIsAdmin() == false)
- {
- return;
- }
- #endif
- CiGetCurrentMachineHashNew(current_hash_new);
- CiGetCurrentMachineHash(current_hash);
- CiGetCurrentMachineHashOld(current_hash_old);
- if (CiReadLastMachineHash(saved_hash) == false)
- {
- CiWriteLastMachineHash(current_hash_new);
- return;
- }
- if (Cmp(saved_hash, current_hash_old, SHA1_SIZE) == 0)
- {
- CiWriteLastMachineHash(current_hash_new);
- return;
- }
- if (Cmp(saved_hash, current_hash, SHA1_SIZE) == 0)
- {
- CiWriteLastMachineHash(current_hash_new);
- return;
- }
- if (Cmp(saved_hash, current_hash_new, SHA1_SIZE) == 0)
- {
- return;
- }
- if (CiWriteLastMachineHash(current_hash_new) == false)
- {
- return;
- }
- CiChangeAllVLanMacAddress(c);
- }
- // Get current machine hash (Old)
- void CiGetCurrentMachineHashOld(void *data)
- {
- char name[MAX_PATH];
- char *product_id = NULL;
- // Validate arguments
- if (data == NULL)
- {
- return;
- }
- #ifdef OS_WIN32
- // Priduct ID
- product_id = MsRegReadStr(REG_LOCAL_MACHINE, "SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion", "ProductId");
- if (product_id == NULL)
- {
- product_id = MsRegReadStr(REG_LOCAL_MACHINE, "SOFTWARE\\Microsoft\\Windows\\CurrentVersion", "ProductId");
- }
- StrCpy(name, sizeof(name), product_id);
- Free(product_id);
- #else // OS_WIN32
- GetMachineName(name, sizeof(name));
- #endif // OS_WIN32
- Trim(name);
- StrUpper(name);
- Hash(data, name, StrLen(name), true);
- }
- // Get current machine hash
- void CiGetCurrentMachineHash(void *data)
- {
- char name[MAX_PATH];
- char *product_id = NULL;
- // Validate arguments
- if (data == NULL)
- {
- return;
- }
- GetMachineName(name, sizeof(name));
- Trim(name);
- StrUpper(name);
- Hash(data, name, StrLen(name), true);
- }
- // Get current machine hash (without using domain name)
- void CiGetCurrentMachineHashNew(void *data)
- {
- char name[MAX_PATH];
- char *p;
- // Validate arguments
- if (data == NULL)
- {
- return;
- }
- GetMachineName(name, sizeof(name));
- // Ignore after first period(.)
- for(p=name; *p; p++)
- if(*p == '.')
- *p = 0;
- Trim(name);
- StrUpper(name);
- Hash(data, name, StrLen(name), true);
- }
- // Write machine hash
- bool CiWriteLastMachineHash(void *data)
- {
- // Validate arguments
- if (data == NULL)
- {
- return false;
- }
- #ifdef OS_WIN32
- if (MsRegWriteBinEx(REG_LOCAL_MACHINE, MS_REG_TCP_SETTING_KEY, "LastMachineHash", data, SHA1_SIZE, true) == false)
- {
- return false;
- }
- return true;
- #else // OS_WIN32
- return false;
- #endif // OS_WIN32
- }
- // Get previous machine hash
- bool CiReadLastMachineHash(void *data)
- {
- BUF *b = NULL;
- // Validate arguments
- if (data == NULL)
- {
- return false;
- }
- #ifdef OS_WIN32
- b = MsRegReadBinEx(REG_LOCAL_MACHINE, MS_REG_TCP_SETTING_KEY, "LastMachineHash", true);
- if (b == NULL)
- {
- return false;
- }
- if (b->Size == SHA1_SIZE)
- {
- Copy(data, b->Buf, b->Size);
- FreeBuf(b);
- return true;
- }
- FreeBuf(b);
- return false;
- #else // OS_WIN32
- return false;
- #endif // OS_WIN32
- }
- // If the MAC address of each virtual LAN card has been eliminated, set it to random numbers
- // (measures for Windows 8 -> 8.1 upgrade problem)
- void CiChangeAllVLanMacAddressIfCleared(CLIENT *c)
- {
- #ifdef OS_WIN32
- RPC_CLIENT_ENUM_VLAN t;
- // Validate arguments
- if (c == NULL)
- {
- return;
- }
- if (MsIsInfCatalogRequired() == false)
- {
- // Not required for other than Windows 8
- return;
- }
- Zero(&t, sizeof(t));
- if (CtEnumVLan(c, &t))
- {
- UINT i;
- for (i = 0;i < t.NumItem;i++)
- {
- RPC_CLIENT_ENUM_VLAN_ITEM *e = t.Items[i];
- UCHAR mac[6];
- if (StrToMac(mac, e->MacAddress))
- {
- if (mac[0] == 0x00 &&
- mac[1] == 0x00 &&
- mac[2] == 0x01 &&
- mac[3] == 0x00 &&
- mac[4] == 0x00 &&
- mac[5] == 0x01)
- {
- char *name = e->DeviceName;
- RPC_CLIENT_SET_VLAN s;
- UCHAR mac[6];
- GenMacAddress(mac);
- Zero(&s, sizeof(s));
- StrCpy(s.DeviceName, sizeof(s.DeviceName), name);
- MacToStr(s.MacAddress, sizeof(s.MacAddress), mac);
- CtSetVLan(c, &s);
- }
- }
- }
- CiFreeClientEnumVLan(&t);
- }
- #endif // OS_WIN32
- }
- // Set the MAC address of all virtual LAN cards to random number
- void CiChangeAllVLanMacAddress(CLIENT *c)
- {
- RPC_CLIENT_ENUM_VLAN t;
- // Validate arguments
- if (c == NULL)
- {
- return;
- }
- Zero(&t, sizeof(t));
- if (CtEnumVLan(c, &t))
- {
- UINT i;
- for (i = 0;i < t.NumItem;i++)
- {
- RPC_CLIENT_ENUM_VLAN_ITEM *e = t.Items[i];
- UCHAR mac[6];
- if (StrToMac(mac, e->MacAddress) && mac[1] == 0xAC)
- {
- char *name = e->DeviceName;
- RPC_CLIENT_SET_VLAN s;
- UCHAR mac[6];
- GenMacAddress(mac);
- Zero(&s, sizeof(s));
- StrCpy(s.DeviceName, sizeof(s.DeviceName), name);
- MacToStr(s.MacAddress, sizeof(s.MacAddress), mac);
- CtSetVLan(c, &s);
- }
- }
- CiFreeClientEnumVLan(&t);
- }
- }
- // Wait for preparation of notification service to complete
- void CnWaitForCnServiceReady()
- {
- UINT64 start_time = Tick64();
- while ((start_time + (UINT64)CLIENT_WAIT_CN_READY_TIMEOUT) >= Tick64())
- {
- if (CnIsCnServiceReady())
- {
- break;
- }
- SleepThread(100);
- }
- }
- // Check whether preparation of notification service completed
- bool CnIsCnServiceReady()
- {
- SOCK *s;
- // Confirm running the notification service
- if (CnCheckAlreadyExists(false) == false)
- {
- // Not running
- return false;
- }
- // Try to connect to the TCP port
- s = ConnectEx("localhost", CLIENT_NOTIFY_PORT, 500);
- if (s == NULL)
- {
- // The TCP port is not opened
- return false;
- }
- Disconnect(s);
- ReleaseSock(s);
- // Running
- return true;
- }
- // Check whether the notification service is already running
- bool CnCheckAlreadyExists(bool lock)
- {
- bool ret = false;
- #ifdef OS_WIN32
- ret = Win32CnCheckAlreadyExists(lock);
- #endif
- return ret;
- }
- typedef struct CNC_STATUS_PRINTER_WINDOW_PARAM
- {
- THREAD *Thread;
- SESSION *Session;
- SOCK *Sock;
- } CNC_STATUS_PRINTER_WINDOW_PARAM;
- typedef struct CNC_CONNECT_ERROR_DLG_THREAD_PARAM
- {
- SESSION *Session;
- SOCK *Sock;
- bool HaltThread;
- EVENT *Event;
- } CNC_CONNECT_ERROR_DLG_THREAD_PARAM;
- // Get the file name of vpnclient.exe in Win32
- char *CiGetVpnClientExeFileName()
- {
- if (Is64() == false)
- {
- return CLIENT_WIN32_EXE_FILENAME;
- }
- else
- {
- if (IsX64())
- {
- return CLIENT_WIN32_EXE_FILENAME_X64;
- }
- else
- {
- return CLIENT_WIN32_EXE_FILENAME_IA64;
- }
- }
- }
- // Thread to stop forcibly the Certificate check dialog client
- void CncCheckCertHaltThread(THREAD *thread, void *param)
- {
- CNC_CONNECT_ERROR_DLG_THREAD_PARAM *dp = (CNC_CONNECT_ERROR_DLG_THREAD_PARAM *)param;
- // Validate arguments
- if (thread == NULL || param == NULL)
- {
- return;
- }
- while (true)
- {
- if (dp->Session->Halt || dp->HaltThread)
- {
- break;
- }
- Wait(dp->Event, 100);
- }
- Disconnect(dp->Sock);
- }
- // Show the certification check dialog
- void CncCheckCert(SESSION *session, UI_CHECKCERT *dlg)
- {
- SOCK *s;
- PACK *p;
- CNC_CONNECT_ERROR_DLG_THREAD_PARAM *dp;
- THREAD *t;
- // Validate arguments
- if (dlg == NULL || session == NULL)
- {
- return;
- }
- s = CncConnect();
- if (s == NULL)
- {
- return;
- }
- p = NewPack();
- PackAddStr(p, "function", "check_cert");
- PackAddUniStr(p, "AccountName", dlg->AccountName);
- PackAddStr(p, "ServerName", dlg->ServerName);
- PackAddX(p, "x", dlg->x);
- PackAddX(p, "parent_x", dlg->parent_x);
- PackAddX(p, "old_x", dlg->old_x);
- PackAddBool(p, "DiffWarning", dlg->DiffWarning);
- PackAddBool(p, "Ok", dlg->Ok);
- PackAddBool(p, "SaveServerCert", dlg->SaveServerCert);
- SendPack(s, p);
- FreePack(p);
- dp = ZeroMalloc(sizeof(CNC_CONNECT_ERROR_DLG_THREAD_PARAM));
- dp->Sock = s;
- dp->Event = NewEvent();
- dp->Session = session;
- t = NewThread(CncCheckCertHaltThread, dp);
- p = RecvPack(s);
- if (p != NULL)
- {
- dlg->Ok = PackGetBool(p, "Ok");
- dlg->DiffWarning = PackGetBool(p, "DiffWarning");
- dlg->SaveServerCert = PackGetBool(p, "SaveServerCert");
- FreePack(p);
- }
- dp->HaltThread = true;
- Set(dp->Event);
- WaitThread(t, INFINITE);
- ReleaseEvent(dp->Event);
- Free(dp);
- ReleaseThread(t);
- Disconnect(s);
- ReleaseSock(s);
- }
- // Smart card signature dialog
- bool CncSecureSignDlg(SECURE_SIGN *sign)
- {
- SOCK *s;
- PACK *p;
- bool ret = false;
- // Validate arguments
- if (sign == NULL)
- {
- return false;
- }
- s = CncConnect();
- if (s == NULL)
- {
- return false;
- }
- p = NewPack();
- PackAddStr(p, "function", "secure_sign");
- OutRpcSecureSign(p, sign);
- SendPack(s, p);
- FreePack(p);
- p = RecvPack(s);
- if (p != NULL)
- {
- ret = PackGetBool(p, "ret");
- if (ret)
- {
- FreeRpcSecureSign(sign);
- Zero(sign, sizeof(SECURE_SIGN));
- InRpcSecureSign(sign, p);
- }
- FreePack(p);
- }
- Disconnect(s);
- ReleaseSock(s);
- return ret;
- }
- // Show the NIC information dialog
- SOCK *CncNicInfo(UI_NICINFO *info)
- {
- SOCK *s;
- PACK *p;
- bool ret = false;
- // Validate arguments
- if (info == NULL)
- {
- return NULL;
- }
- s = CncConnectEx(200);
- if (s == NULL)
- {
- return NULL;
- }
- p = NewPack();
- PackAddStr(p, "function", "nicinfo");
- PackAddStr(p, "NicName", info->NicName);
- PackAddUniStr(p, "AccountName", info->AccountName);
- SendPack(s, p);
- FreePack(p);
- return s;
- }
- // Close the NIC information dialog
- void CncNicInfoFree(SOCK *s)
- {
- // Validate arguments
- if (s == NULL)
- {
- return;
- }
- Disconnect(s);
- ReleaseSock(s);
- }
- // Show the message dialog
- SOCK *CncMsgDlg(UI_MSG_DLG *dlg)
- {
- SOCK *s;
- PACK *p;
- bool ret = false;
- char *utf;
- // Validate arguments
- if (dlg == NULL)
- {
- return NULL;
- }
- s = CncConnectEx(200);
- if (s == NULL)
- {
- return NULL;
- }
- p = NewPack();
- PackAddStr(p, "function", "msg_dialog");
- PackAddStr(p, "ServerName", dlg->ServerName);
- PackAddStr(p, "HubName", dlg->HubName);
- utf = CopyUniToUtf(dlg->Msg);
- PackAddData(p, "Msg", utf, StrLen(utf));
- Free(utf);
- SendPack(s, p);
- FreePack(p);
- return s;
- }
- // Close the message dialog
- void CndMsgDlgFree(SOCK *s)
- {
- // Validate arguments
- if (s == NULL)
- {
- return;
- }
- Disconnect(s);
- ReleaseSock(s);
- }
- // The thread to stop the password input dialog client forcibly
- void CncPasswordDlgHaltThread(THREAD *thread, void *param)
- {
- CNC_CONNECT_ERROR_DLG_THREAD_PARAM *dp = (CNC_CONNECT_ERROR_DLG_THREAD_PARAM *)param;
- // Validate arguments
- if (thread == NULL || param == NULL)
- {
- return;
- }
- while (true)
- {
- if (dp->Session->Halt || dp->HaltThread)
- {
- break;
- }
- Wait(dp->Event, 100);
- }
- Disconnect(dp->Sock);
- }
- // Show the password input dialog
- bool CncPasswordDlg(SESSION *session, UI_PASSWORD_DLG *dlg)
- {
- SOCK *s;
- PACK *p;
- CNC_CONNECT_ERROR_DLG_THREAD_PARAM *dp;
- THREAD *t;
- bool ret = false;
- // Validate arguments
- if (dlg == NULL || session == NULL)
- {
- return false;
- }
- s = CncConnect();
- if (s == NULL)
- {
- Wait(session->HaltEvent, session->RetryInterval);
- return true;
- }
- p = NewPack();
- PackAddStr(p, "function", "password_dialog");
- PackAddInt(p, "Type", dlg->Type);
- PackAddStr(p, "Username", dlg->Username);
- PackAddStr(p, "Password", dlg->Password);
- PackAddStr(p, "ServerName", dlg->ServerName);
- PackAddInt(p, "RetryIntervalSec", dlg->RetryIntervalSec);
- PackAddBool(p, "ProxyServer", dlg->ProxyServer);
- PackAddBool(p, "AdminMode", dlg->AdminMode);
- PackAddBool(p, "ShowNoSavePassword", dlg->ShowNoSavePassword);
- PackAddBool(p, "NoSavePassword", dlg->NoSavePassword);
- SendPack(s, p);
- FreePack(p);
- dp = ZeroMalloc(sizeof(CNC_CONNECT_ERROR_DLG_THREAD_PARAM));
- dp->Session = session;
- dp->Sock = s;
- dp->Event = NewEvent();
- t = NewThread(CncConnectErrorDlgHaltThread, dp);
- p = RecvPack(s);
- if (p != NULL)
- {
- ret = PackGetBool(p, "ok");
- dlg->NoSavePassword = PackGetBool(p, "NoSavePassword");
- dlg->ProxyServer = PackGetBool(p, "ProxyServer");
- dlg->Type = PackGetInt(p, "Type");
- PackGetStr(p, "Username", dlg->Username, sizeof(dlg->Username));
- PackGetStr(p, "Password", dlg->Password, sizeof(dlg->Password));
- FreePack(p);
- }
- dp->HaltThread = true;
- Set(dp->Event);
- WaitThread(t, INFINITE);
- ReleaseEvent(dp->Event);
- Free(dp);
- ReleaseThread(t);
- Disconnect(s);
- ReleaseSock(s);
- return ret;
- }
- // Thread to stop the connection error dialog client forcibly
- void CncConnectErrorDlgHaltThread(THREAD *thread, void *param)
- {
- CNC_CONNECT_ERROR_DLG_THREAD_PARAM *dp = (CNC_CONNECT_ERROR_DLG_THREAD_PARAM *)param;
- // Validate arguments
- if (thread == NULL || param == NULL)
- {
- return;
- }
- while (true)
- {
- if (dp->Session->Halt || dp->HaltThread)
- {
- break;
- }
- Wait(dp->Event, 100);
- }
- Disconnect(dp->Sock);
- }
- // Show the connection error dialog
- bool CncConnectErrorDlg(SESSION *session, UI_CONNECTERROR_DLG *dlg)
- {
- SOCK *s;
- PACK *p;
- CNC_CONNECT_ERROR_DLG_THREAD_PARAM *dp;
- THREAD *t;
- bool ret = false;
- // Validate arguments
- if (dlg == NULL || session == NULL)
- {
- return false;
- }
- s = CncConnect();
- if (s == NULL)
- {
- Wait(session->HaltEvent, session->RetryInterval);
- return true;
- }
- p = NewPack();
- PackAddStr(p, "function", "connecterror_dialog");
- PackAddUniStr(p, "AccountName", dlg->AccountName);
- PackAddStr(p, "ServerName", dlg->ServerName);
- PackAddInt(p, "Err", dlg->Err);
- PackAddInt(p, "CurrentRetryCount", dlg->CurrentRetryCount);
- PackAddInt(p, "RetryLimit", dlg->RetryLimit);
- PackAddInt(p, "RetryIntervalSec", dlg->RetryIntervalSec);
- PackAddBool(p, "HideWindow", dlg->HideWindow);
- SendPack(s, p);
- FreePack(p);
- dp = ZeroMalloc(sizeof(CNC_CONNECT_ERROR_DLG_THREAD_PARAM));
- dp->Session = session;
- dp->Sock = s;
- dp->Event = NewEvent();
- t = NewThread(CncConnectErrorDlgHaltThread, dp);
- p = RecvPack(s);
- if (p != NULL)
- {
- ret = PackGetBool(p, "ok");
- dlg->HideWindow = PackGetBool(p, "HideWindow");
- FreePack(p);
- }
- dp->HaltThread = true;
- Set(dp->Event);
- WaitThread(t, INFINITE);
- ReleaseEvent(dp->Event);
- Free(dp);
- ReleaseThread(t);
- Disconnect(s);
- ReleaseSock(s);
- return ret;
- }
- // Thread for the status indicator client
- void CncStatusPrinterWindowThreadProc(THREAD *thread, void *param)
- {
- CNC_STATUS_PRINTER_WINDOW_PARAM *pp;
- SOCK *sock;
- PACK *p;
- // Validate arguments
- if (thread == NULL || param == NULL)
- {
- return;
- }
- pp = (CNC_STATUS_PRINTER_WINDOW_PARAM *)param;
- sock = pp->Sock;
- pp->Thread = thread;
- AddRef(pp->Thread->ref);
- NoticeThreadInit(thread);
- p = RecvPack(sock);
- if (p != NULL)
- {
- // Stop the session
- StopSessionEx(pp->Session, true);
- FreePack(p);
- }
- }
- // Create a status indicator client
- SOCK *CncStatusPrinterWindowStart(SESSION *s)
- {
- SOCK *sock;
- PACK *p;
- THREAD *t;
- CNC_STATUS_PRINTER_WINDOW_PARAM *param;
- // Validate arguments
- if (s == NULL)
- {
- return NULL;
- }
- sock = CncConnect();
- if (sock == NULL)
- {
- return NULL;
- }
- p = NewPack();
- PackAddStr(p, "function", "status_printer");
- PackAddUniStr(p, "account_name", s->Account->ClientOption->AccountName);
- if (SendPack(sock, p) == false)
- {
- FreePack(p);
- ReleaseSock(sock);
- return NULL;
- }
- FreePack(p);
- param = ZeroMalloc(sizeof(CNC_STATUS_PRINTER_WINDOW_PARAM));
- param->Sock = sock;
- param->Session = s;
- sock->Param = param;
- t = NewThread(CncStatusPrinterWindowThreadProc, param);
- WaitThreadInit(t);
- ReleaseThread(t);
- return sock;
- }
- // Send a string to the status indicator
- void CncStatusPrinterWindowPrint(SOCK *s, wchar_t *str)
- {
- CNC_STATUS_PRINTER_WINDOW_PARAM *param;
- PACK *p;
- // Validate arguments
- if (s == NULL || str == NULL)
- {
- return;
- }
- param = (CNC_STATUS_PRINTER_WINDOW_PARAM *)s->Param;
- p = NewPack();
- PackAddUniStr(p, "string", str);
- SendPack(s, p);
- FreePack(p);
- }
- // Stop the status indicator client
- void CncStatusPrinterWindowStop(SOCK *s)
- {
- CNC_STATUS_PRINTER_WINDOW_PARAM *param;
- // Validate arguments
- if (s == NULL)
- {
- return;
- }
- param = (CNC_STATUS_PRINTER_WINDOW_PARAM *)s->Param;
- // Disconnect the client socket
- Disconnect(s);
- // Terminate the thread
- WaitThread(param->Thread, INFINITE);
- ReleaseThread(param->Thread);
- Free(param);
- ReleaseSock(s);
- }
- // Start the driver installer for Windows Vista
- bool CncExecDriverInstaller(char *arg)
- {
- SOCK *s = CncConnect();
- PACK *p;
- bool ret;
- if (s == NULL)
- {
- return false;
- }
- p = NewPack();
- PackAddStr(p, "function", "exec_driver_installer");
- PackAddStr(p, "arg", arg);
- SendPack(s, p);
- FreePack(p);
- p = RecvPack(s);
- if (p == NULL)
- {
- Disconnect(s);
- ReleaseSock(s);
- return false;
- }
- ret = PackGetBool(p, "ret");
- FreePack(p);
- Disconnect(s);
- ReleaseSock(s);
- return ret;
- }
- // Let the current running client notification services releasing the socket
- void CncReleaseSocket()
- {
- SOCK *s = CncConnect();
- PACK *p;
- if (s == NULL)
- {
- return;
- }
- p = NewPack();
- PackAddStr(p, "function", "release_socket");
- #ifdef OS_WIN32
- PackAddInt(p, "pid", MsGetProcessId());
- #endif // OS_WIN32
- SendPack(s, p);
- FreePack(p);
- Disconnect(s);
- ReleaseSock(s);
- }
- // Get the Session ID of the client notification service
- UINT CncGetSessionId()
- {
- SOCK *s = CncConnect();
- PACK *p;
- UINT ret;
- if (s == NULL)
- {
- return INFINITE;
- }
- p = NewPack();
- PackAddStr(p, "function", "get_session_id");
- SendPack(s, p);
- FreePack(p);
- p = RecvPack(s);
- if (p == NULL)
- {
- Disconnect(s);
- ReleaseSock(s);
- return INFINITE;
- }
- ret = PackGetInt(p, "session_id");
- FreePack(p);
- Disconnect(s);
- ReleaseSock(s);
- return ret;
- }
- // Terminate the process of the client notification service
- void CncExit()
- {
- SOCK *s = CncConnectEx(256);
- PACK *p;
- if (s != NULL)
- {
- p = NewPack();
- PackAddStr(p, "function", "exit");
- SendPack(s, p);
- FreePack(p);
- FreePack(RecvPack(s));
- Disconnect(s);
- ReleaseSock(s);
- }
- #ifdef OS_WIN32
- MsKillOtherInstanceEx("vpnclient");
- #endif // OS_WIN32
- }
- // Connect to the client notification service
- SOCK *CncConnect()
- {
- return CncConnectEx(0);
- }
- SOCK *CncConnectEx(UINT timeout)
- {
- SOCK *s = ConnectEx("localhost", CLIENT_NOTIFY_PORT, timeout);
- return s;
- }
- #ifdef OS_WIN32
- // Thread for the certificate check dialog
- void Win32CnCheckCertThreadProc(THREAD *thread, void *param)
- {
- UI_CHECKCERT *dlg;
- // Validate arguments
- if (thread == NULL || param == NULL)
- {
- return;
- }
- dlg = (UI_CHECKCERT *)param;
- CheckCertDlg(dlg);
- {
- PACK *p = NewPack();
- PackAddBool(p, "Ok", dlg->Ok);
- PackAddBool(p, "SaveServerCert", dlg->SaveServerCert);
- SendPack(dlg->Sock, p);
- FreePack(p);
- FreePack(RecvPack(dlg->Sock));
- }
- Disconnect(dlg->Sock);
- }
- // Certificate check dialog
- void Win32CnCheckCert(SOCK *s, PACK *p)
- {
- UI_CHECKCERT dlg;
- THREAD *t;
- Zero(&dlg, sizeof(dlg));
- // Validate arguments
- if (s == NULL || p == NULL)
- {
- return;
- }
- PackGetUniStr(p, "AccountName", dlg.AccountName, sizeof(dlg.AccountName));
- PackGetStr(p, "ServerName", dlg.ServerName, sizeof(dlg.ServerName));
- dlg.x = PackGetX(p, "x");
- dlg.parent_x = PackGetX(p, "parent_x");
- dlg.old_x = PackGetX(p, "old_x");
- dlg.DiffWarning = PackGetBool(p, "DiffWarning");
- dlg.Ok = PackGetBool(p, "Ok");
- dlg.SaveServerCert = PackGetBool(p, "SaveServerCert");
- dlg.Sock = s;
- t = NewThread(Win32CnCheckCertThreadProc, &dlg);
- FreePack(RecvPack(s));
- dlg.Halt = true;
- WaitThread(t, INFINITE);
- ReleaseThread(t);
- FreeX(dlg.parent_x);
- FreeX(dlg.old_x);
- FreeX(dlg.x);
- }
- // Message display dialog thread procedure
- void Win32CnMsgDlgThreadProc(THREAD *thread, void *param)
- {
- UI_MSG_DLG *dlg = (UI_MSG_DLG *)param;
- wchar_t tmp[MAX_SIZE];
- char url[MAX_SIZE];
- // Validate arguments
- if (thread == NULL || dlg == NULL)
- {
- return;
- }
- UniFormat(tmp, sizeof(tmp), _UU("CM_MSG_TITLE"),
- dlg->ServerName, dlg->HubName);
- if (IsURLMsg(dlg->Msg, url, sizeof(url)) == false)
- {
- OnceMsgEx(NULL, tmp, dlg->Msg, true, 167, &dlg->Halt);
- }
- else
- {
- if (MsExecute(url, NULL) == false)
- {
- OnceMsgEx(NULL, tmp, dlg->Msg, true, 167, &dlg->Halt);
- }
- }
- Disconnect(dlg->Sock);
- }
- // NIC information dialog thread procedure
- void Win32CnNicInfoThreadProc(THREAD *thread, void *param)
- {
- UI_NICINFO *info = (UI_NICINFO *)param;
- // Validate arguments
- if (thread == NULL || info == NULL)
- {
- return;
- }
- if (MsIsNt())
- {
- // Do not show a dialog on Windows 9x system
- NicInfo(info);
- }
- Disconnect(info->Sock);
- }
- // NIC information dialog
- void Win32CnNicInfo(SOCK *s, PACK *p)
- {
- UI_NICINFO info;
- THREAD *t;
- Zero(&info, sizeof(info));
- // Validate arguments
- if (s == NULL || p == NULL)
- {
- return;
- }
- PackGetStr(p, "NicName", info.NicName, sizeof(info.NicName));
- PackGetUniStr(p, "AccountName", info.AccountName, sizeof(info.AccountName));
- info.Sock = s;
- t = NewThread(Win32CnNicInfoThreadProc, &info);
- FreePack(RecvPack(s));
- info.Halt = true;
- WaitThread(t, INFINITE);
- ReleaseThread(t);
- }
- // Message display dialog
- void Win32CnMsgDlg(SOCK *s, PACK *p)
- {
- UI_MSG_DLG dlg;
- THREAD *t;
- UINT utf_size;
- char *utf;
- wchar_t *msg;
- Zero(&dlg, sizeof(dlg));
- // Validate arguments
- if (s == NULL || p == NULL)
- {
- return;
- }
- PackGetStr(p, "ServerName", dlg.ServerName, sizeof(dlg.ServerName));
- PackGetStr(p, "HubName", dlg.HubName, sizeof(dlg.HubName));
- utf_size = PackGetDataSize(p, "Msg");
- utf = ZeroMalloc(utf_size + 8);
- PackGetData(p, "Msg", utf);
- msg = CopyUtfToUni(utf);
- Free(utf);
- dlg.Sock = s;
- dlg.Msg = msg;
- t = NewThread(Win32CnMsgDlgThreadProc, &dlg);
- FreePack(RecvPack(s));
- dlg.Halt = true;
- WaitThread(t, INFINITE);
- ReleaseThread(t);
- Free(msg);
- }
- // Thread for Password input dialog
- void Win32CnPasswordDlgThreadProc(THREAD *thread, void *param)
- {
- UI_PASSWORD_DLG *dlg;
- // Validate arguments
- if (thread == NULL || param == NULL)
- {
- return;
- }
- dlg = (UI_PASSWORD_DLG *)param;
- if (PasswordDlg(NULL, dlg))
- {
- PACK *p = NewPack();
- PackAddBool(p, "ok", true);
- PackAddStr(p, "Username", dlg->Username);
- PackAddStr(p, "Password", dlg->Password);
- PackAddInt(p, "Type", dlg->Type);
- PackAddBool(p, "ProxyServer", dlg->ProxyServer);
- PackAddBool(p, "NoSavePassword", dlg->NoSavePassword);
- SendPack(dlg->Sock, p);
- FreePack(p);
- FreePack(RecvPack(dlg->Sock));
- }
- Disconnect(dlg->Sock);
- }
- // Password input dialog
- void Win32CnPasswordDlg(SOCK *s, PACK *p)
- {
- UI_PASSWORD_DLG dlg;
- THREAD *t = NULL;
- Zero(&dlg, sizeof(dlg));
- // Validate arguments
- if (s == NULL || p == NULL)
- {
- return;
- }
- dlg.Type = PackGetInt(p, "Type");
- PackGetStr(p, "Username", dlg.Username, sizeof(dlg.Username));
- PackGetStr(p, "Password", dlg.Password, sizeof(dlg.Password));
- PackGetStr(p, "ServerName", dlg.ServerName, sizeof(dlg.ServerName));
- dlg.RetryIntervalSec = PackGetInt(p, "RetryIntervalSec");
- dlg.ProxyServer = PackGetBool(p, "ProxyServer");
- dlg.AdminMode = PackGetBool(p, "AdminMode");
- dlg.ShowNoSavePassword = PackGetBool(p, "ShowNoSavePassword");
- dlg.NoSavePassword = PackGetBool(p, "NoSavePassword");
- dlg.CancelEvent = NewEvent();
- dlg.Sock = s;
- t = NewThread(Win32CnPasswordDlgThreadProc, &dlg);
- FreePack(RecvPack(s));
- Set(dlg.CancelEvent);
- WaitThread(t, INFINITE);
- ReleaseEvent(dlg.CancelEvent);
- ReleaseThread(t);
- }
- // Thread for the connection error dialog
- void Win32CnConnectErrorDlgThreadProc(THREAD *thread, void *param)
- {
- UI_CONNECTERROR_DLG *dlg;
- // Validate arguments
- if (thread == NULL || param == NULL)
- {
- return;
- }
- dlg = (UI_CONNECTERROR_DLG *)param;
- if (ConnectErrorDlg(dlg))
- {
- PACK *p = NewPack();
- PackAddBool(p, "ok", true);
- PackAddBool(p, "HideWindow", dlg->HideWindow);
- SendPack(dlg->Sock, p);
- FreePack(p);
- FreePack(RecvPack(dlg->Sock));
- }
- Disconnect(dlg->Sock);
- }
- // Connection Error dialog (Win32)
- void Win32CnConnectErrorDlg(SOCK *s, PACK *p)
- {
- UI_CONNECTERROR_DLG dlg;
- THREAD *t;
- Zero(&dlg, sizeof(dlg));
- // Validate arguments
- if (s == NULL || p == NULL)
- {
- return;
- }
- PackGetUniStr(p, "AccountName", dlg.AccountName, sizeof(dlg.AccountName));
- PackGetStr(p, "ServerName", dlg.ServerName, sizeof(dlg.ServerName));
- dlg.Err = PackGetInt(p, "Err");
- dlg.CurrentRetryCount = PackGetInt(p, "CurrentRetryCount");
- dlg.RetryLimit = PackGetInt(p, "RetryLimit");
- dlg.RetryIntervalSec = PackGetInt(p, "RetryIntervalSec");
- dlg.HideWindow = PackGetBool(p, "HideWindow");
- dlg.CancelEvent = NewEvent();
- dlg.Sock = s;
- t = NewThread(Win32CnConnectErrorDlgThreadProc, &dlg);
- FreePack(RecvPack(s));
- Set(dlg.CancelEvent);
- WaitThread(t, INFINITE);
- ReleaseEvent(dlg.CancelEvent);
- ReleaseThread(t);
- }
- // Status indicator (Win32)
- void Win32CnStatusPrinter(SOCK *s, PACK *p)
- {
- STATUS_WINDOW *w;
- wchar_t account_name[MAX_ACCOUNT_NAME_LEN + 1];
- // Validate arguments
- if (s == NULL || p == NULL)
- {
- return;
- }
- PackGetUniStr(p, "account_name", account_name, sizeof(account_name));
- w = StatusPrinterWindowStart(s, account_name);
- while (true)
- {
- PACK *p = RecvPack(s);
- if (p == NULL)
- {
- // Exit the dialog because it is disconnected
- break;
- }
- else
- {
- wchar_t tmp[MAX_SIZE];
- // Rewrite the string
- PackGetUniStr(p, "string", tmp, sizeof(tmp));
- StatusPrinterWindowPrint(w, tmp);
- FreePack(p);
- }
- }
- StatusPrinterWindowStop(w);
- }
- // Start the driver installer (for Windows Vista)
- void Win32CnExecDriverInstaller(SOCK *s, PACK *p)
- {
- char arg[MAX_SIZE];
- bool ret;
- void *helper = NULL;
- // Validate arguments
- if (s == NULL || p == NULL)
- {
- return;
- }
- if (PackGetStr(p, "arg", arg, sizeof(arg)) == false)
- {
- return;
- }
- if (MsIsVista())
- {
- helper = CmStartUacHelper();
- }
- ret = MsExecDriverInstaller(arg);
- CmStopUacHelper(helper);
- p = NewPack();
- PackAddBool(p, "ret", ret);
- SendPack(s, p);
- FreePack(p);
- }
- #endif // OS_WIN32
- // Start the driver installer
- void CnExecDriverInstaller(SOCK *s, PACK *p)
- {
- // Validate arguments
- if (s == NULL || p == NULL)
- {
- return;
- }
- #ifdef OS_WIN32
- Win32CnExecDriverInstaller(s, p);
- #endif // OS_WIN32
- }
- // Certificate confirmation dialog
- void CnCheckCert(SOCK *s, PACK *p)
- {
- // Validate arguments
- if (s == NULL || p == NULL)
- {
- return;
- }
- #ifdef OS_WIN32
- Win32CnCheckCert(s, p);
- #endif // OS_WIN32
- }
- // NIC information dialog
- void CnNicInfo(SOCK *s, PACK *p)
- {
- // Validate arguments
- if (s == NULL || p == NULL)
- {
- return;
- }
- #ifdef OS_WIN32
- Win32CnNicInfo(s, p);
- #endif // OS_WIN32
- }
- // Message display dialog
- void CnMsgDlg(SOCK *s, PACK *p)
- {
- // Validate arguments
- if (s == NULL || p == NULL)
- {
- return;
- }
- #ifdef OS_WIN32
- Win32CnMsgDlg(s, p);
- #endif // OS_WIN32
- }
- // Password input dialog
- void CnPasswordDlg(SOCK *s, PACK *p)
- {
- // Validate arguments
- if (s == NULL || p == NULL)
- {
- return;
- }
- #ifdef OS_WIN32
- Win32CnPasswordDlg(s, p);
- #endif // OS_WIN32
- }
- // Connection Error dialog
- void CnConnectErrorDlg(SOCK *s, PACK *p)
- {
- // Validate arguments
- if (s == NULL || p == NULL)
- {
- return;
- }
- #ifdef OS_WIN32
- Win32CnConnectErrorDlg(s, p);
- #endif // OS_WIN32
- }
- // Status indicator
- void CnStatusPrinter(SOCK *s, PACK *p)
- {
- // Validate arguments
- if (s == NULL || p == NULL)
- {
- return;
- }
- #ifdef OS_WIN32
- Win32CnStatusPrinter(s, p);
- #endif // OS_WIN32
- }
- // Client notification service listener thread
- void CnListenerProc(THREAD *thread, void *param)
- {
- TCP_ACCEPTED_PARAM *data = (TCP_ACCEPTED_PARAM *)param;
- SOCK *s;
- PACK *p;
- // Validate arguments
- if (data == NULL || thread == NULL)
- {
- return;
- }
- #ifdef OS_WIN32
- //Set Application ID
- JL_SetCurrentProcessExplicitAppUserModelID(APPID_CM);
- #endif // OS_WIN32
- s = data->s;
- AddRef(s->ref);
- NoticeThreadInit(thread);
- if (s->LocalIP.addr[0] == 127)
- {
- p = RecvPack(s);
- if (p != NULL)
- {
- char function[MAX_SIZE];
- if (PackGetStr(p, "function", function, sizeof(function)))
- {
- if (StrCmpi(function, "status_printer") == 0)
- {
- CnStatusPrinter(s, p);
- }
- else if (StrCmpi(function, "connecterror_dialog") == 0)
- {
- CnConnectErrorDlg(s, p);
- }
- else if (StrCmpi(function, "msg_dialog") == 0)
- {
- CnMsgDlg(s, p);
- }
- else if (StrCmpi(function, "nicinfo") == 0)
- {
- CnNicInfo(s, p);
- }
- else if (StrCmpi(function, "password_dialog") == 0)
- {
- CnPasswordDlg(s, p);
- }
- else if (StrCmpi(function, "secure_sign") == 0)
- {
- CnSecureSign(s, p);
- }
- else if (StrCmpi(function, "check_cert") == 0)
- {
- CnCheckCert(s, p);
- }
- else if (StrCmpi(function, "exit") == 0)
- {
- #ifdef OS_WIN32
- MsTerminateProcess();
- #else // OS_WIN32
- _exit(0);
- #endif // OS_WIN32
- }
- else if (StrCmpi(function, "get_session_id") == 0)
- {
- PACK *p = NewPack();
- #ifdef OS_WIN32
- PackAddInt(p, "session_id", MsGetCurrentTerminalSessionId());
- #endif // OS_WIN32
- SendPack(s, p);
- FreePack(p);
- }
- else if (StrCmpi(function, "exec_driver_installer") == 0)
- {
- CnExecDriverInstaller(s, p);
- }
- else if (StrCmpi(function, "release_socket") == 0)
- {
- // Stop the listener
- CnReleaseSocket(s, p);
- }
- }
- FreePack(p);
- }
- }
- Disconnect(s);
- ReleaseSock(s);
- }
- // Do the Secure Sign
- void CnSecureSign(SOCK *s, PACK *p)
- {
- SECURE_SIGN sign;
- bool ret = false;
- // Validate arguments
- if (s == NULL || p == NULL)
- {
- return;
- }
- Zero(&sign, sizeof(sign));
- InRpcSecureSign(&sign, p);
- #ifdef OS_WIN32
- // Win32: Show dialog
- ret = Win32CiSecureSign(&sign);
- #else // OS_WIN32
- // UNIX: not implemented
- ret = false;
- #endif // OS_WIN32
- p = NewPack();
- OutRpcSecureSign(p, &sign);
- FreeRpcSecureSign(&sign);
- PackAddBool(p, "ret", ret);
- SendPack(s, p);
- FreePack(p);
- }
- // Stop the listener
- void CnReleaseSocket(SOCK *s, PACK *p)
- {
- UINT pid = 0;
- UINT current_pid = 0;
- // Validate arguments
- if (s == NULL || p == NULL)
- {
- return;
- }
- pid = PackGetInt(p, "pid");
- #ifdef OS_WIN32
- current_pid = MsGetProcessId();
- #endif // OS_WIN32
- if (current_pid == pid)
- {
- return;
- }
- Lock(cn_listener_lock);
- {
- if (cn_listener != NULL)
- {
- if (cn_listener->Halt == false)
- {
- StopListener(cn_listener);
- cn_next_allow = Tick64() + (6 * 1000);
- }
- }
- }
- Unlock(cn_listener_lock);
- }
- // Start the client notification service
- void CnStart()
- {
- CEDAR *cedar;
- LISTENER *o;
- UINT last_cursor_hash = 0;
- bool last_session_active = false;
- cn_next_allow = 0;
- cn_listener_lock = NewLock();
- #ifdef OS_WIN32
- MsSetShutdownParameters(0xff, 0x00000001);
- InitWinUi(_UU("CN_TITLE"), _SS("DEFAULT_FONT"), _II("DEFAULT_FONT_SIZE"));
- #endif // OS_WIN32
- cedar = NewCedar(NULL, NULL);
- if (CnCheckAlreadyExists(true))
- {
- // Already started
- ReleaseCedar(cedar);
- #ifdef OS_WIN32
- FreeWinUi();
- #endif // OS_WIN32
- return;
- }
- #ifdef OS_WIN32
- MsRegWriteInt(REG_CURRENT_USER, CM_REG_KEY,
- "NotifyServerProcessId", MsGetProcessId());
- #endif // OS_WIN32
- DisableDosProtect();
- BEGIN_LISTENER:
- Lock(cn_listener_lock);
- cn_listener = o = NewListenerEx2(cedar, LISTENER_TCP, CLIENT_NOTIFY_PORT, CnListenerProc, NULL, true);
- Unlock(cn_listener_lock);
- while (true)
- {
- UINT current_cursor_hash = 0;
- bool cursor_changed = false;
- #ifdef OS_WIN32
- // Get the current cursor position
- current_cursor_hash = MsGetCursorPosHash();
- #endif // OS_WIN32
- if (last_cursor_hash != current_cursor_hash)
- {
- // Check the cursor position
- cursor_changed = true;
- last_cursor_hash = current_cursor_hash;
- }
- Lock(cn_listener_lock);
- // Check the status periodically after that the listener has started
- if (cn_listener->Status == LISTENER_STATUS_TRYING || cn_listener->Halt)
- {
- bool session_active = false;
- #ifdef OS_WIN32
- session_active = MsIsCurrentTerminalSessionActive();
- if (cursor_changed)
- {
- // If the cursor position is changed but the terminal session is
- // not active, the cursor position is regarded as not changed.
- if (session_active == false)
- {
- cursor_changed = false;
- }
- }
- if (last_session_active != session_active)
- {
- //If the cursor position doesn't changed but the terminal session
- // became active than previous, the cursor position is regarded as changed.
- last_session_active = session_active;
- if (session_active)
- {
- cursor_changed = true;
- }
- }
- #endif // OS_WIN32
- // If the port cannot be opened
- if (cn_next_allow <= Tick64())
- {
- if (cursor_changed || cn_listener->Halt)
- {
- if (cursor_changed)
- {
- // It can be judged to have the rights to open the port
- // since the mouse cursor is moving.
- // So, take over the port which is owned by other process forcibly
- CncReleaseSocket();
- }
- if (cn_listener->Halt)
- {
- ReleaseListener(cn_listener);
- cn_listener = NULL;
- Unlock(cn_listener_lock);
- goto BEGIN_LISTENER;
- }
- }
- }
- }
- Unlock(cn_listener_lock);
- SleepThread(1000);
- }
- }
- // Confirm whether the account file is parsed successfully
- bool CiTryToParseAccount(BUF *b)
- {
- RPC_CLIENT_CREATE_ACCOUNT *a;
- // Validate arguments
- if (b == NULL)
- {
- return false;
- }
- a = CiCfgToAccount(b);
- if (a != NULL)
- {
- CiFreeClientCreateAccount(a);
- Free(a);
- return true;
- }
- else
- {
- return false;
- }
- }
- bool CiTryToParseAccountFile(wchar_t *name)
- {
- bool ret;
- BUF *b;
- // Validate arguments
- if (name == NULL)
- {
- return false;
- }
- b = ReadDumpW(name);
- if (b == NULL)
- {
- return false;
- }
- ret = CiTryToParseAccount(b);
- FreeBuf(b);
- return ret;
- }
- // Confirm whether the account information includes sensitive information
- bool CiHasAccountSensitiveInformation(BUF *b)
- {
- RPC_CLIENT_CREATE_ACCOUNT *a;
- bool ret = false;
- // Validate arguments
- if (b == NULL)
- {
- return false;
- }
- a = CiCfgToAccount(b);
- if (a == NULL)
- {
- return false;
- }
- if (a->ClientAuth->AuthType == CLIENT_AUTHTYPE_PASSWORD)
- {
- ret = true;
- }
- else if (a->ClientAuth->AuthType == CLIENT_AUTHTYPE_PLAIN_PASSWORD)
- {
- ret = true;
- }
- CiFreeClientCreateAccount(a);
- Free(a);
- return ret;
- }
- bool CiHasAccountSensitiveInformationFile(wchar_t *name)
- {
- bool ret = false;
- BUF *b;
- // Validate arguments
- if (name == NULL)
- {
- return false;
- }
- b = ReadDumpW(name);
- if (b == NULL)
- {
- return false;
- }
- ret = CiHasAccountSensitiveInformation(b);
- FreeBuf(b);
- return ret;
- }
- // Delete the sensitive information in the account information
- bool CiEraseSensitiveInAccount(BUF *b)
- {
- RPC_CLIENT_CREATE_ACCOUNT *a;
- BUF *b2;
- bool ret = false;
- // Validate arguments
- if (b == NULL)
- {
- return false;
- }
- a = CiCfgToAccount(b);
- if (a == NULL)
- {
- return false;
- }
- if (a->ClientAuth->AuthType == CLIENT_AUTHTYPE_PASSWORD)
- {
- Zero(a->ClientAuth->HashedPassword, sizeof(a->ClientAuth->HashedPassword));
- ClearStr(a->ClientAuth->Username, sizeof(a->ClientAuth->Username));
- }
- else if (a->ClientAuth->AuthType == CLIENT_AUTHTYPE_PLAIN_PASSWORD)
- {
- ClearStr(a->ClientAuth->PlainPassword, sizeof(a->ClientAuth->PlainPassword));
- ClearStr(a->ClientAuth->Username, sizeof(a->ClientAuth->Username));
- }
- b2 = CiAccountToCfg(a);
- if (b2 != NULL)
- {
- ret = true;
- ClearBuf(b);
- WriteBuf(b, b2->Buf, b2->Size);
- SeekBuf(b, 0, 0);
- FreeBuf(b2);
- }
- CiFreeClientCreateAccount(a);
- Free(a);
- return ret;
- }
- // Read the account information from the buffer
- RPC_CLIENT_CREATE_ACCOUNT *CiCfgToAccount(BUF *b)
- {
- RPC_CLIENT_CREATE_ACCOUNT *t;
- FOLDER *f;
- ACCOUNT *a;
- // Validate arguments
- if (b == NULL)
- {
- return NULL;
- }
- f = CfgBufTextToFolder(b);
- if (f == NULL)
- {
- return NULL;
- }
- a = CiLoadClientAccount(f);
- CfgDeleteFolder(f);
- if (a == NULL)
- {
- return NULL;
- }
- DeleteLock(a->lock);
- t = ZeroMalloc(sizeof(RPC_CLIENT_CREATE_ACCOUNT));
- t->ClientOption = a->ClientOption;
- t->ClientAuth = a->ClientAuth;
- t->StartupAccount = a->StartupAccount;
- t->CheckServerCert = a->CheckServerCert;
- t->ServerCert = a->ServerCert;
- Free(a);
- return t;
- }
- // Write the account information to a buffer
- BUF *CiAccountToCfg(RPC_CLIENT_CREATE_ACCOUNT *t)
- {
- BUF *b;
- FOLDER *root;
- ACCOUNT a;
- // Validate arguments
- if (t == NULL)
- {
- return NULL;
- }
- root = CfgCreateFolder(NULL, TAG_ROOT);
- Zero(&a, sizeof(a));
- a.ClientOption = t->ClientOption;
- a.ClientAuth = t->ClientAuth;
- a.CheckServerCert = t->CheckServerCert;
- a.ServerCert = t->ServerCert;
- a.StartupAccount = t->StartupAccount;
- CiWriteAccountData(root, &a);
- b = CfgFolderToBufEx(root, true, true);
- CfgDeleteFolder(root);
- return b;
- }
- // RPC dispatch routine
- PACK *CiRpcDispatch(RPC *rpc, char *name, PACK *p)
- {
- CLIENT *c = rpc->Param;
- PACK *ret;
- // Validate arguments
- if (rpc == NULL || name == NULL || p == NULL)
- {
- return NULL;
- }
- ret = NewPack();
- if (StrCmpi(name, "GetClientVersion") == 0)
- {
- RPC_CLIENT_VERSION a;
- if (CtGetClientVersion(c, &a) == false)
- {
- RpcError(ret, c->Err);
- }
- else
- {
- OutRpcClientVersion(ret, &a);
- }
- }
- else if (StrCmpi(name, "GetCmSetting") == 0)
- {
- CM_SETTING a;
- if (CtGetCmSetting(c, &a) == false)
- {
- RpcError(ret, c->Err);
- }
- else
- {
- OutRpcCmSetting(ret, &a);
- }
- }
- else if (StrCmpi(name, "SetCmSetting") == 0)
- {
- CM_SETTING a;
- Zero(&a, sizeof(a));
- InRpcCmSetting(&a, p);
- if (CtSetCmSetting(c, &a) == false)
- {
- RpcError(ret, c->Err);
- }
- }
- else if (StrCmpi(name, "SetPassword") == 0)
- {
- RPC_CLIENT_PASSWORD a;
- InRpcClientPassword(&a, p);
- if (CtSetPassword(c, &a) == false)
- {
- RpcError(ret, c->Err);
- }
- }
- else if (StrCmpi(name, "GetPasswordSetting") == 0)
- {
- RPC_CLIENT_PASSWORD_SETTING a;
- if (CtGetPasswordSetting(c, &a) == false)
- {
- RpcError(ret, c->Err);
- }
- else
- {
- OutRpcClientPasswordSetting(ret, &a);
- }
- }
- else if (StrCmpi(name, "EnumCa") == 0)
- {
- RPC_CLIENT_ENUM_CA a;
- if (CtEnumCa(c, &a) == false)
- {
- RpcError(ret, c->Err);
- }
- else
- {
- OutRpcClientEnumCa(ret, &a);
- CiFreeClientEnumCa(&a);
- }
- }
- else if (StrCmpi(name, "AddCa") == 0)
- {
- RPC_CERT a;
- InRpcCert(&a, p);
- if (CtAddCa(c, &a) == false)
- {
- RpcError(ret, c->Err);
- }
- FreeX(a.x);
- }
- else if (StrCmpi(name, "DeleteCa") == 0)
- {
- RPC_CLIENT_DELETE_CA a;
- InRpcClientDeleteCa(&a, p);
- if (CtDeleteCa(c, &a) == false)
- {
- RpcError(ret, c->Err);
- }
- }
- else if (StrCmpi(name, "GetCa") == 0)
- {
- RPC_GET_CA a;
- InRpcGetCa(&a, p);
- if (CtGetCa(c, &a) == false)
- {
- RpcError(ret, c->Err);
- }
- else
- {
- OutRpcGetCa(ret, &a);
- }
- CiFreeGetCa(&a);
- }
- else if (StrCmpi(name, "EnumSecure") == 0)
- {
- RPC_CLIENT_ENUM_SECURE a;
- if (CtEnumSecure(c, &a) == false)
- {
- RpcError(ret, c->Err);
- }
- else
- {
- OutRpcClientEnumSecure(ret, &a);
- CiFreeClientEnumSecure(&a);
- }
- }
- else if (StrCmpi(name, "UseSecure") == 0)
- {
- RPC_USE_SECURE a;
- InRpcUseSecure(&a, p);
- if (CtUseSecure(c, &a) == false)
- {
- RpcError(ret, c->Err);
- }
- }
- else if (StrCmpi(name, "GetUseSecure") == 0)
- {
- RPC_USE_SECURE a;
- Zero(&a, sizeof(a));
- if (CtGetUseSecure(c, &a) == false)
- {
- RpcError(ret, c->Err);
- }
- else
- {
- OutRpcUseSecure(ret, &a);
- }
- }
- else if (StrCmpi(name, "EnumObjectInSecure") == 0)
- {
- RPC_ENUM_OBJECT_IN_SECURE a;
- if (CtEnumObjectInSecure(c, &a) == false)
- {
- RpcError(ret, c->Err);
- }
- else
- {
- OutRpcEnumObjectInSecure(ret, &a);
- CiFreeEnumObjectInSecure(&a);
- }
- }
- else if (StrCmpi(name, "CreateVLan") == 0)
- {
- RPC_CLIENT_CREATE_VLAN a;
- InRpcCreateVLan(&a, p);
- if (CtCreateVLan(c, &a) == false)
- {
- RpcError(ret, c->Err);
- }
- }
- else if (StrCmpi(name, "UpgradeVLan") == 0)
- {
- RPC_CLIENT_CREATE_VLAN a;
- InRpcCreateVLan(&a, p);
- if (CtUpgradeVLan(c, &a) == false)
- {
- RpcError(ret, c->Err);
- }
- }
- else if (StrCmpi(name, "GetVLan") == 0)
- {
- RPC_CLIENT_GET_VLAN a;
- InRpcClientGetVLan(&a, p);
- if (CtGetVLan(c, &a) == false)
- {
- RpcError(ret, c->Err);
- }
- else
- {
- OutRpcClientGetVLan(ret, &a);
- }
- }
- else if (StrCmpi(name, "SetVLan") == 0)
- {
- RPC_CLIENT_SET_VLAN a;
- InRpcClientSetVLan(&a, p);
- if (CtSetVLan(c, &a) == false)
- {
- RpcError(ret, c->Err);
- }
- }
- else if (StrCmpi(name, "EnumVLan") == 0)
- {
- RPC_CLIENT_ENUM_VLAN a;
- if (CtEnumVLan(c, &a) == false)
- {
- RpcError(ret, c->Err);
- }
- else
- {
- OutRpcClientEnumVLan(ret, &a);
- CiFreeClientEnumVLan(&a);
- }
- }
- else if (StrCmpi(name, "DeleteVLan") == 0)
- {
- RPC_CLIENT_CREATE_VLAN a;
- InRpcCreateVLan(&a, p);
- if (CtDeleteVLan(c, &a) == false)
- {
- RpcError(ret, c->Err);
- }
- }
- else if (StrCmpi(name, "EnableVLan") == 0)
- {
- RPC_CLIENT_CREATE_VLAN a;
- InRpcCreateVLan(&a, p);
- if (CtEnableVLan(c, &a) == false)
- {
- RpcError(ret, c->Err);
- }
- }
- else if (StrCmpi(name, "DisableVLan") == 0)
- {
- RPC_CLIENT_CREATE_VLAN a;
- InRpcCreateVLan(&a, p);
- if (CtDisableVLan(c, &a) == false)
- {
- RpcError(ret, c->Err);
- }
- }
- else if (StrCmpi(name, "CreateAccount") == 0)
- {
- RPC_CLIENT_CREATE_ACCOUNT a;
- InRpcClientCreateAccount(&a, p);
- if (CtCreateAccount(c, &a, false) == false)
- {
- RpcError(ret, c->Err);
- }
- CiFreeClientCreateAccount(&a);
- }
- else if (StrCmpi(name, "EnumAccount") == 0)
- {
- RPC_CLIENT_ENUM_ACCOUNT a;
- if (CtEnumAccount(c, &a) == false)
- {
- RpcError(ret, c->Err);
- }
- else
- {
- OutRpcClientEnumAccount(ret, &a);
- CiFreeClientEnumAccount(&a);
- }
- }
- else if (StrCmpi(name, "DeleteAccount") == 0)
- {
- RPC_CLIENT_DELETE_ACCOUNT a;
- InRpcClientDeleteAccount(&a, p);
- if (CtDeleteAccount(c, &a, false) == false)
- {
- RpcError(ret, c->Err);
- }
- }
- else if (StrCmpi(name, "SetStartupAccount") == 0)
- {
- RPC_CLIENT_DELETE_ACCOUNT a;
- InRpcClientDeleteAccount(&a, p);
- if (CtSetStartupAccount(c, &a, false) == false)
- {
- RpcError(ret, c->Err);
- }
- }
- else if (StrCmpi(name, "RemoveStartupAccount") == 0)
- {
- RPC_CLIENT_DELETE_ACCOUNT a;
- InRpcClientDeleteAccount(&a, p);
- if (CtRemoveStartupAccount(c, &a) == false)
- {
- RpcError(ret, c->Err);
- }
- }
- else if (StrCmpi(name, "GetIssuer") == 0)
- {
- RPC_GET_ISSUER a;
- InRpcGetIssuer(&a, p);
- if (CtGetIssuer(c, &a))
- {
- OutRpcGetIssuer(ret, &a);
- }
- else
- {
- RpcError(ret, c->Err);
- }
- CiFreeGetIssuer(&a);
- }
- else if (StrCmpi(name, "GetCommonProxySetting") == 0)
- {
- INTERNET_SETTING t;
- InRpcInternetSetting(&t, p);
- if (CtGetCommonProxySetting(c, &t))
- {
- OutRpcInternetSetting(ret, &t);
- }
- else
- {
- RpcError(ret, c->Err);
- }
- }
- else if (StrCmpi(name, "SetCommonProxySetting") == 0)
- {
- INTERNET_SETTING t;
- InRpcInternetSetting(&t, p);
- if (CtSetCommonProxySetting(c, &t))
- {
- OutRpcInternetSetting(ret, &t);
- }
- else
- {
- RpcError(ret, c->Err);
- }
- }
- else if (StrCmpi(name, "SetAccount") == 0)
- {
- RPC_CLIENT_CREATE_ACCOUNT a;
- InRpcClientCreateAccount(&a, p);
- if (CtSetAccount(c, &a, false) == false)
- {
- RpcError(ret, c->Err);
- }
- CiFreeClientCreateAccount(&a);
- }
- else if (StrCmpi(name, "GetAccount") == 0)
- {
- RPC_CLIENT_GET_ACCOUNT a;
- InRpcClientGetAccount(&a, p);
- if (CtGetAccount(c, &a) == false)
- {
- RpcError(ret, c->Err);
- }
- else
- {
- OutRpcClientGetAccount(ret, &a);
- }
- CiFreeClientGetAccount(&a);
- }
- else if (StrCmpi(name, "RenameAccount") == 0)
- {
- RPC_RENAME_ACCOUNT a;
- InRpcRenameAccount(&a, p);
- if (CtRenameAccount(c, &a, false) == false)
- {
- RpcError(ret, c->Err);
- }
- }
- else if (StrCmpi(name, "SetClientConfig") == 0)
- {
- CLIENT_CONFIG a;
- InRpcClientConfig(&a, p);
- if (CtSetClientConfig(c, &a) == false)
- {
- RpcError(ret, c->Err);
- }
- }
- else if (StrCmpi(name, "GetClientConfig") == 0)
- {
- CLIENT_CONFIG a;
- if (CtGetClientConfig(c, &a) == false)
- {
- RpcError(ret, c->Err);
- }
- else
- {
- OutRpcClientConfig(ret, &a);
- }
- }
- else if (StrCmpi(name, "Connect") == 0)
- {
- RPC_CLIENT_CONNECT a;
- InRpcClientConnect(&a, p);
- if (CtConnect(c, &a) == false)
- {
- RpcError(ret, c->Err);
- }
- }
- else if (StrCmpi(name, "Disconnect") == 0)
- {
- RPC_CLIENT_CONNECT a;
- InRpcClientConnect(&a, p);
- if (CtDisconnect(c, &a, false) == false)
- {
- RpcError(ret, c->Err);
- }
- }
- else if (StrCmpi(name, "GetAccountStatus") == 0)
- {
- RPC_CLIENT_GET_CONNECTION_STATUS a;
- InRpcClientGetConnectionStatus(&a, p);
- if (CtGetAccountStatus(c, &a) == false)
- {
- RpcError(ret, c->Err);
- }
- else
- {
- OutRpcClientGetConnectionStatus(ret, &a);
- }
- CiFreeClientGetConnectionStatus(&a);
- }
- else
- {
- FreePack(ret);
- ret = NULL;
- }
- return ret;
- }
- // Set the CM_SETTING
- UINT CcSetCmSetting(REMOTE_CLIENT *r, CM_SETTING *a)
- {
- PACK *ret, *p;
- UINT err;
- // Validate arguments
- if (r == NULL || a == NULL)
- {
- return ERR_INTERNAL_ERROR;
- }
- p = NewPack();
- OutRpcCmSetting(p, a);
- ret = RpcCall(r->Rpc, "SetCmSetting", p);
- if (RpcIsOk(ret))
- {
- FreePack(ret);
- return 0;
- }
- else
- {
- err = RpcGetError(ret);
- FreePack(ret);
- return err;
- }
- }
- // Get the CM_SETTING
- UINT CcGetCmSetting(REMOTE_CLIENT *r, CM_SETTING *a)
- {
- PACK *ret;
- // Validate arguments
- if (r == NULL || a == NULL)
- {
- return ERR_INTERNAL_ERROR;
- }
- ret = RpcCall(r->Rpc, "GetCmSetting", NULL);
- if (RpcIsOk(ret))
- {
- InRpcCmSetting(a, ret);
- FreePack(ret);
- return 0;
- }
- else
- {
- UINT err = RpcGetError(ret);
- FreePack(ret);
- return err;
- }
- }
- // Get the client version
- UINT CcGetClientVersion(REMOTE_CLIENT *r, RPC_CLIENT_VERSION *a)
- {
- PACK *ret;
- // Validate arguments
- if (r == NULL || a == NULL)
- {
- return ERR_INTERNAL_ERROR;
- }
- ret = RpcCall(r->Rpc, "GetClientVersion", NULL);
- if (RpcIsOk(ret))
- {
- InRpcClientVersion(a, ret);
- FreePack(ret);
- return 0;
- }
- else
- {
- UINT err = RpcGetError(ret);
- FreePack(ret);
- return err;
- }
- }
- // Set the password
- UINT CcSetPassword(REMOTE_CLIENT *r, RPC_CLIENT_PASSWORD *pass)
- {
- PACK *ret, *p;
- // Validate arguments
- if (r == NULL || pass == NULL)
- {
- return ERR_INTERNAL_ERROR;
- }
- p = NewPack();
- OutRpcClientPassword(p, pass);
- ret = RpcCall(r->Rpc, "SetPassword", p);
- if (RpcIsOk(ret))
- {
- FreePack(ret);
- return 0;
- }
- else
- {
- UINT err = RpcGetError(ret);
- FreePack(ret);
- return err;
- }
- }
- // Get the password setting
- UINT CcGetPasswordSetting(REMOTE_CLIENT *r, RPC_CLIENT_PASSWORD_SETTING *a)
- {
- PACK *ret;
- UINT err = 0;
- // Validate arguments
- if (r == NULL || a == NULL)
- {
- return ERR_INTERNAL_ERROR;
- }
- ret = RpcCall(r->Rpc, "GetPasswordSetting", NULL);
- if (RpcIsOk(ret))
- {
- InRpcClientPasswordSetting(a, ret);
- }
- else
- {
- err = RpcGetError(ret);
- }
- FreePack(ret);
- return err;
- }
- // Enumerate the CA
- UINT CcEnumCa(REMOTE_CLIENT *r, RPC_CLIENT_ENUM_CA *e)
- {
- PACK *ret;
- UINT err = 0;
- // Validate arguments
- if (r == NULL || e == NULL)
- {
- return ERR_INTERNAL_ERROR;
- }
- ret = RpcCall(r->Rpc, "EnumCa", NULL);
- if (RpcIsOk(ret))
- {
- InRpcClientEnumCa(e, ret);
- }
- else
- {
- err = RpcGetError(ret);
- }
- FreePack(ret);
- return err;
- }
- // Add the CA
- UINT CcAddCa(REMOTE_CLIENT *r, RPC_CERT *cert)
- {
- PACK *p, *ret;
- UINT err = 0;
- // Validate arguments
- if (r == NULL || cert == NULL)
- {
- return ERR_INTERNAL_ERROR;
- }
- p = NewPack();
- OutRpcCert(p, cert);
- ret = RpcCall(r->Rpc, "AddCa", p);
- if (RpcIsOk(ret) == false)
- {
- err = RpcGetError(ret);
- }
- FreePack(ret);
- return err;
- }
- // Delete the CA
- UINT CcDeleteCa(REMOTE_CLIENT *r, RPC_CLIENT_DELETE_CA *c)
- {
- PACK *p, *ret;
- UINT err = 0;
- // Validate arguments
- if (r == NULL || c == NULL)
- {
- return ERR_INTERNAL_ERROR;
- }
- p = NewPack();
- OutRpcClientDeleteCa(p, c);
- ret = RpcCall(r->Rpc, "DeleteCa", p);
- if (RpcIsOk(ret) == false)
- {
- err = RpcGetError(ret);
- }
- FreePack(ret);
- return err;
- }
- // Get the proxy setting
- UINT CcGetCommonProxySetting(REMOTE_CLIENT *r, INTERNET_SETTING *a)
- {
- PACK *p, *ret;
- UINT err = 0;
- // Validate arguments
- if (r == NULL || a == NULL)
- {
- return ERR_INTERNAL_ERROR;
- }
- p = NewPack();
- OutRpcInternetSetting(p, a);
- ret = RpcCall(r->Rpc, "GetCommonProxySetting", p);
- if (RpcIsOk(ret))
- {
- Zero(a, sizeof(INTERNET_SETTING));
- InRpcInternetSetting(a, ret);
- }
- else
- {
- err = RpcGetError(ret);
- }
- FreePack(ret);
- return err;
- }
- // Set the proxy setting
- UINT CcSetCommonProxySetting(REMOTE_CLIENT *r, INTERNET_SETTING *a)
- {
- PACK *p, *ret;
- UINT err = 0;
- // Validate arguments
- if (r == NULL || a == NULL)
- {
- return ERR_INTERNAL_ERROR;
- }
- p = NewPack();
- OutRpcInternetSetting(p, a);
- ret = RpcCall(r->Rpc, "SetCommonProxySetting", p);
- if (RpcIsOk(ret))
- {
- Zero(a, sizeof(INTERNET_SETTING));
- InRpcInternetSetting(a, ret);
- }
- else
- {
- err = RpcGetError(ret);
- }
- FreePack(ret);
- return err;
- }
- // Get the issuer
- UINT CcGetIssuer(REMOTE_CLIENT *r, RPC_GET_ISSUER *a)
- {
- PACK *p, *ret;
- UINT err = 0;
- // Validate arguments
- if (r == NULL || a == NULL)
- {
- return ERR_INTERNAL_ERROR;
- }
- p = NewPack();
- OutRpcGetIssuer(p, a);
- ret = RpcCall(r->Rpc, "GetIssuer", p);
- if (RpcIsOk(ret))
- {
- if (a->x != NULL)
- {
- FreeX(a->x);
- a->x = NULL;
- }
- InRpcGetIssuer(a, ret);
- }
- else
- {
- err = RpcGetError(ret);
- }
- FreePack(ret);
- return err;
- }
- // Get the CA
- UINT CcGetCa(REMOTE_CLIENT *r, RPC_GET_CA *get)
- {
- PACK *p, *ret;
- UINT err = 0;
- // Validate arguments
- if (r == NULL || get == NULL)
- {
- return ERR_INTERNAL_ERROR;
- }
- p = NewPack();
- OutRpcGetCa(p, get);
- ret = RpcCall(r->Rpc, "GetCa", p);
- if (RpcIsOk(ret))
- {
- InRpcGetCa(get, ret);
- }
- else
- {
- err = RpcGetError(ret);
- }
- FreePack(ret);
- return err;
- }
- // Enumeration of the secure devices
- UINT CcEnumSecure(REMOTE_CLIENT *r, RPC_CLIENT_ENUM_SECURE *e)
- {
- PACK *ret;
- UINT err = 0;
- // Validate arguments
- if (r == NULL || e == NULL)
- {
- return ERR_INTERNAL_ERROR;
- }
- ret = RpcCall(r->Rpc, "EnumSecure", NULL);
- if (RpcIsOk(ret))
- {
- InRpcClientEnumSecure(e, ret);
- }
- else
- {
- err = RpcGetError(ret);
- }
- FreePack(ret);
- return err;
- }
- // Get the secure device that the user is using
- UINT CcGetUseSecure(REMOTE_CLIENT *r, RPC_USE_SECURE *sec)
- {
- PACK *p, *ret;
- UINT err = 0;
- // Validate arguments
- if (r == NULL || sec == NULL)
- {
- return ERR_INTERNAL_ERROR;
- }
- p = NewPack();
- ret = RpcCall(r->Rpc, "GetUseSecure", p);
- if (RpcIsOk(ret) == false)
- {
- err = RpcGetError(ret);
- }
- else
- {
- InRpcUseSecure(sec, ret);
- }
- FreePack(ret);
- return err;
- }
- // Use the secure device
- UINT CcUseSecure(REMOTE_CLIENT *r, RPC_USE_SECURE *sec)
- {
- PACK *p, *ret;
- UINT err = 0;
- // Validate arguments
- if (r == NULL || sec == NULL)
- {
- return ERR_INTERNAL_ERROR;
- }
- p = NewPack();
- OutRpcUseSecure(p, sec);
- ret = RpcCall(r->Rpc, "UseSecure", p);
- if (RpcIsOk(ret) == false)
- {
- err = RpcGetError(ret);
- }
- FreePack(ret);
- return err;
- }
- // Enumerate objects in the secure device
- UINT CcEnumObjectInSecure(REMOTE_CLIENT *r, RPC_ENUM_OBJECT_IN_SECURE *e)
- {
- PACK *ret;
- UINT err = 0;
- // Validate arguments
- if (r == NULL || e == NULL)
- {
- return ERR_INTERNAL_ERROR;
- }
- ret = RpcCall(r->Rpc, "EnumObjectInSecure", NULL);
- if (RpcIsOk(ret))
- {
- InRpcEnumObjectInSecure(e, ret);
- }
- else
- {
- err = RpcGetError(ret);
- }
- FreePack(ret);
- return err;
- }
- // Get a next recommended virtual LAN card name
- bool CiGetNextRecommendedVLanName(REMOTE_CLIENT *r, char *name, UINT size)
- {
- RPC_CLIENT_ENUM_VLAN t;
- UINT i;
- bool b;
- UINT j;
- bool ok = false;
- // Validate arguments
- if (r == NULL || name == NULL)
- {
- return false;
- }
- Zero(&t, sizeof(t));
- if (CcEnumVLan(r, &t) != ERR_NO_ERROR)
- {
- return false;
- }
- for (i = 1;i < 128;i++)
- {
- char tmp[MAX_SIZE];
- CiGenerateVLanRegulatedName(tmp, sizeof(tmp), i);
- b = false;
- for (j = 0;j < t.NumItem;j++)
- {
- if (StrCmpi(t.Items[j]->DeviceName, tmp) == 0)
- {
- b = true;
- break;
- }
- }
- if (b == false)
- {
- ok = true;
- StrCpy(name, size, tmp);
- break;
- }
- }
- if (ok)
- {
- CiFreeClientEnumVLan(&t);
- }
- return true;
- }
- // Generate a virtual LAN card name automatically
- void CiGenerateVLanRegulatedName(char *name, UINT size, UINT i)
- {
- // Validate arguments
- if (name == NULL)
- {
- return;
- }
- if (i == 1)
- {
- StrCpy(name, size, "VPN");
- }
- else
- {
- Format(name, size, "VPN%u", i);
- }
- }
- // Examine whether the specified name is valid as a virtual LAN card name of Windows 8 and later?
- bool CiIsValidVLanRegulatedName(char *name)
- {
- UINT i;
- // Validate arguments
- if (name == NULL)
- {
- return false;
- }
- for (i = 1;i < 128;i++)
- {
- char tmp[MAX_SIZE];
- CiGenerateVLanRegulatedName(tmp, sizeof(tmp), i);
- if (StrCmpi(name, tmp) == 0)
- {
- return true;
- }
- }
- return false;
- }
- // Create a VLAN
- UINT CcCreateVLan(REMOTE_CLIENT *r, RPC_CLIENT_CREATE_VLAN *create)
- {
- PACK *ret, *p;
- UINT err = 0;
- char *s = NULL;
- // Validate arguments
- if (r == NULL || create == NULL)
- {
- return ERR_INTERNAL_ERROR;
- }
- p = NewPack();
- OutRpcCreateVLan(p, create);
- #ifdef OS_WIN32
- s = MsNoWarningSoundInit();
- #endif // OS_WIN32
- ret = RpcCall(r->Rpc, "CreateVLan", p);
- #ifdef OS_WIN32
- MsNoWarningSoundFree(s);
- #endif // OS_WIN32
- if (RpcIsOk(ret) == false)
- {
- err = RpcGetError(ret);
- }
- FreePack(ret);
- return err;
- }
- // Upgrade the VLAN
- UINT CcUpgradeVLan(REMOTE_CLIENT *r, RPC_CLIENT_CREATE_VLAN *create)
- {
- PACK *ret, *p;
- UINT err = 0;
- char *s = NULL;
- // Validate arguments
- if (r == NULL || create == NULL)
- {
- return ERR_INTERNAL_ERROR;
- }
- p = NewPack();
- OutRpcCreateVLan(p, create);
- #ifdef OS_WIN32
- s = MsNoWarningSoundInit();
- #endif // OS_WIN32
- ret = RpcCall(r->Rpc, "UpgradeVLan", p);
- #ifdef OS_WIN32
- MsNoWarningSoundFree(s);
- #endif // OS_WIN32
- if (RpcIsOk(ret) == false)
- {
- err = RpcGetError(ret);
- }
- FreePack(ret);
- return err;
- }
- // Get the VLAN
- UINT CcGetVLan(REMOTE_CLIENT *r, RPC_CLIENT_GET_VLAN *get)
- {
- PACK *ret, *p;
- UINT err = 0;
- // Validate arguments
- if (r == NULL || get == NULL)
- {
- return ERR_INTERNAL_ERROR;
- }
- p = NewPack();
- OutRpcClientGetVLan(p, get);
- ret = RpcCall(r->Rpc, "GetVLan", p);
- if (RpcIsOk(ret))
- {
- InRpcClientGetVLan(get, ret);
- }
- else
- {
- err = RpcGetError(ret);
- }
- FreePack(ret);
- return err;
- }
- // VLAN configuration
- UINT CcSetVLan(REMOTE_CLIENT *r, RPC_CLIENT_SET_VLAN *set)
- {
- PACK *ret, *p;
- UINT err = 0;
- // Validate arguments
- if (r == NULL || set == NULL)
- {
- return ERR_INTERNAL_ERROR;
- }
- p = NewPack();
- OutRpcClientSetVLan(p, set);
- ret = RpcCall(r->Rpc, "SetVLan", p);
- if (RpcIsOk(ret) == false)
- {
- err = RpcGetError(ret);
- }
- FreePack(ret);
- return err;
- }
- // Enumeration of VLAN
- UINT CcEnumVLan(REMOTE_CLIENT *r, RPC_CLIENT_ENUM_VLAN *e)
- {
- PACK *ret;
- UINT err = 0;
- // Validate arguments
- if (r == NULL || e == NULL)
- {
- return ERR_INTERNAL_ERROR;
- }
- ret = RpcCall(r->Rpc, "EnumVLan", NULL);
- if (RpcIsOk(ret))
- {
- InRpcClientEnumVLan(e, ret);
- }
- else
- {
- err = RpcGetError(ret);
- }
- FreePack(ret);
- return err;
- }
- // Delete the VLAN
- UINT CcDeleteVLan(REMOTE_CLIENT *r, RPC_CLIENT_CREATE_VLAN *d)
- {
- PACK *ret, *p;
- UINT err = 0;
- // Validate arguments
- if (r == NULL || d == NULL)
- {
- return ERR_INTERNAL_ERROR;
- }
- p = NewPack();
- OutRpcCreateVLan(p, d);
- ret = RpcCall(r->Rpc, "DeleteVLan", p);
- if (RpcIsOk(ret) == false)
- {
- err = RpcGetError(ret);
- }
- FreePack(ret);
- return err;
- }
- // Enable the VLAN
- UINT CcEnableVLan(REMOTE_CLIENT *r, RPC_CLIENT_CREATE_VLAN *vlan)
- {
- PACK *ret, *p;
- UINT err = 0;
- // Validate arguments
- if (r == NULL || vlan == NULL)
- {
- return ERR_INTERNAL_ERROR;
- }
- p = NewPack();
- OutRpcCreateVLan(p, vlan);
- ret = RpcCall(r->Rpc, "EnableVLan", p);
- if (RpcIsOk(ret) == false)
- {
- err = RpcGetError(ret);
- }
- FreePack(ret);
- return err;
- }
- // Disable the VLAN
- UINT CcDisableVLan(REMOTE_CLIENT *r, RPC_CLIENT_CREATE_VLAN *vlan)
- {
- PACK *ret, *p;
- UINT err = 0;
- // Validate arguments
- if (r == NULL || vlan == NULL)
- {
- return ERR_INTERNAL_ERROR;
- }
- p = NewPack();
- OutRpcCreateVLan(p, vlan);
- ret = RpcCall(r->Rpc, "DisableVLan", p);
- if (RpcIsOk(ret) == false)
- {
- err = RpcGetError(ret);
- }
- FreePack(ret);
- return err;
- }
- // Create an Account
- UINT CcCreateAccount(REMOTE_CLIENT *r, RPC_CLIENT_CREATE_ACCOUNT *a)
- {
- PACK *ret, *p;
- UINT err = 0;
- // Validate arguments
- if (r == NULL || a == NULL)
- {
- return ERR_INTERNAL_ERROR;
- }
- p = NewPack();
- OutRpcClientCreateAccount(p, a);
- ret = RpcCall(r->Rpc, "CreateAccount", p);
- if (RpcIsOk(ret) == false)
- {
- err = RpcGetError(ret);
- }
- FreePack(ret);
- return err;
- }
- // Enumeration of accounts
- UINT CcEnumAccount(REMOTE_CLIENT *r, RPC_CLIENT_ENUM_ACCOUNT *e)
- {
- PACK *ret;
- UINT err = 0;
- // Validate arguments
- if (r == NULL || e == NULL)
- {
- return ERR_INTERNAL_ERROR;
- }
- ret = RpcCall(r->Rpc, "EnumAccount", NULL);
- if (RpcIsOk(ret))
- {
- UINT i;
- InRpcClientEnumAccount(e, ret);
- for (i = 0;i < e->NumItem;i++)
- {
- RPC_CLIENT_ENUM_ACCOUNT_ITEM *t = e->Items[i];
- if (IsEmptyStr(t->HubName) && t->Port == 0)
- {
- UINT err2;
- RPC_CLIENT_GET_ACCOUNT a;
- // Because the Client Manager can not get the port number and HUB name
- // when enumerating in the VPN Client of the old version, get these separately.
- Zero(&a, sizeof(a));
- UniStrCpy(a.AccountName, sizeof(a.AccountName), t->AccountName);
- err2 = CcGetAccount(r, &a);
- if (err2 == ERR_NO_ERROR)
- {
- StrCpy(t->HubName, sizeof(t->HubName), a.ClientOption->HubName);
- t->Port = a.ClientOption->Port;
- CiFreeClientGetAccount(&a);
- }
- }
- }
- }
- else
- {
- err = RpcGetError(ret);
- }
- FreePack(ret);
- return err;
- }
- // Unset the startup flag of the accout
- UINT CcRemoveStartupAccount(REMOTE_CLIENT *r, RPC_CLIENT_DELETE_ACCOUNT *a)
- {
- PACK *ret, *p;
- UINT err = 0;
- // Validate arguments
- if (r == NULL || a == NULL)
- {
- return ERR_INTERNAL_ERROR;
- }
- p = NewPack();
- OutRpcClientDeleteAccount(p, a);
- ret = RpcCall(r->Rpc, "RemoveStartupAccount", p);
- if (RpcIsOk(ret) == false)
- {
- err = RpcGetError(ret);
- }
- FreePack(ret);
- return err;
- }
- // Set to start-up flag of the account
- UINT CcSetStartupAccount(REMOTE_CLIENT *r, RPC_CLIENT_DELETE_ACCOUNT *a)
- {
- PACK *ret, *p;
- UINT err = 0;
- // Validate arguments
- if (r == NULL || a == NULL)
- {
- return ERR_INTERNAL_ERROR;
- }
- p = NewPack();
- OutRpcClientDeleteAccount(p, a);
- ret = RpcCall(r->Rpc, "SetStartupAccount", p);
- if (RpcIsOk(ret) == false)
- {
- err = RpcGetError(ret);
- }
- FreePack(ret);
- return err;
- }
- // Delete the account
- UINT CcDeleteAccount(REMOTE_CLIENT *r, RPC_CLIENT_DELETE_ACCOUNT *a)
- {
- PACK *ret, *p;
- UINT err = 0;
- // Validate arguments
- if (r == NULL || a == NULL)
- {
- return ERR_INTERNAL_ERROR;
- }
- p = NewPack();
- OutRpcClientDeleteAccount(p, a);
- ret = RpcCall(r->Rpc, "DeleteAccount", p);
- if (RpcIsOk(ret) == false)
- {
- err = RpcGetError(ret);
- }
- FreePack(ret);
- return err;
- }
- // Account setting
- UINT CcSetAccount(REMOTE_CLIENT *r, RPC_CLIENT_CREATE_ACCOUNT *a)
- {
- PACK *ret, *p;
- UINT err = 0;
- // Validate arguments
- if (r == NULL || a == NULL)
- {
- return ERR_INTERNAL_ERROR;
- }
- p = NewPack();
- OutRpcClientCreateAccount(p, a);
- ret = RpcCall(r->Rpc, "SetAccount", p);
- if (RpcIsOk(ret) == false)
- {
- err = RpcGetError(ret);
- }
- FreePack(ret);
- return err;
- }
- // Get the account
- UINT CcGetAccount(REMOTE_CLIENT *r, RPC_CLIENT_GET_ACCOUNT *a)
- {
- PACK *ret, *p;
- UINT err = 0;
- // Validate arguments
- if (r == NULL || a == NULL)
- {
- return ERR_INTERNAL_ERROR;
- }
- p = NewPack();
- OutRpcClientGetAccount(p, a);
- ret = RpcCall(r->Rpc, "GetAccount", p);
- if (RpcIsOk(ret))
- {
- InRpcClientGetAccount(a, ret);
- }
- else
- {
- err = RpcGetError(ret);
- }
- FreePack(ret);
- return err;
- }
- // Change the account name
- UINT CcRenameAccount(REMOTE_CLIENT *r, RPC_RENAME_ACCOUNT *rename)
- {
- PACK *p, *ret;
- UINT err = 0;
- // Validate arguments
- if (r == NULL || rename == NULL)
- {
- return ERR_INTERNAL_ERROR;
- }
- p = NewPack();
- OutRpcRenameAccount(p, rename);
- ret = RpcCall(r->Rpc, "RenameAccount", p);
- if (RpcIsOk(ret) == false)
- {
- err = RpcGetError(ret);
- }
- FreePack(ret);
- return err;
- }
- // Set the Client configuration
- UINT CcSetClientConfig(REMOTE_CLIENT *r, CLIENT_CONFIG *o)
- {
- PACK *p, *ret;
- UINT err = 0;
- // Validate arguments
- if (r == NULL || o == NULL)
- {
- return ERR_INTERNAL_ERROR;
- }
- p = NewPack();
- OutRpcClientConfig(p, o);
- ret = RpcCall(r->Rpc, "SetClientConfig", p);
- if (RpcIsOk(ret) == false)
- {
- err = RpcGetError(ret);
- }
- FreePack(ret);
- return err;
- }
- // Get the client configuration
- UINT CcGetClientConfig(REMOTE_CLIENT *r, CLIENT_CONFIG *o)
- {
- PACK *ret;
- UINT err = 0;
- // Validate arguments
- if (r == NULL || o == NULL)
- {
- return ERR_INTERNAL_ERROR;
- }
- ret = RpcCall(r->Rpc, "GetClientConfig", NULL);
- if (RpcIsOk(ret))
- {
- InRpcClientConfig(o, ret);
- }
- else
- {
- err = RpcGetError(ret);
- }
- FreePack(ret);
- return err;
- }
- // Set the service to foreground process
- void CcSetServiceToForegroundProcess(REMOTE_CLIENT *r)
- {
- // Validate arguments
- if (r == NULL)
- {
- return;
- }
- // Abolition
- /*
- if (r->Rpc != NULL && r->Rpc->Sock != NULL && r->Rpc->Sock->RemoteIP.addr[0] == 127)
- {
- if (OS_IS_WINDOWS_NT(GetOsInfo()->OsType) &&
- GET_KETA(GetOsInfo()->OsType, 100) >= 2)
- {
- // Only on a Windows 2000 or later
- RPC_CLIENT_VERSION v;
- Zero(&v, sizeof(v));
- if (r->ClientBuildInt == 0)
- {
- CcGetClientVersion(r, &v);
- r->ClientBuildInt = v.ClientBuildInt;
- r->ProcessId = v.ProcessId;
- }
- if (r->ProcessId != 0 && r->ClientBuildInt <= 5080)
- {
- #ifdef OS_WIN32
- // Set the service process as a foreground window
- AllowFGWindow(v.ProcessId);
- #endif // OS_WIN32
- }
- }
- }*/
- }
- // Connect
- UINT CcConnect(REMOTE_CLIENT *r, RPC_CLIENT_CONNECT *connect)
- {
- PACK *ret, *p;
- UINT err = 0;
- // Validate arguments
- if (r == NULL || connect == NULL)
- {
- return ERR_INTERNAL_ERROR;
- }
- CcSetServiceToForegroundProcess(r);
- p = NewPack();
- OutRpcClientConnect(p, connect);
- ret = RpcCall(r->Rpc, "Connect", p);
- if (RpcIsOk(ret) == false)
- {
- err = RpcGetError(ret);
- }
- FreePack(ret);
- return err;
- }
- // Disconnect
- UINT CcDisconnect(REMOTE_CLIENT *r, RPC_CLIENT_CONNECT *connect)
- {
- PACK *ret, *p;
- UINT err = 0;
- // Validate arguments
- if (r == NULL || connect == NULL)
- {
- return ERR_INTERNAL_ERROR;
- }
- CcSetServiceToForegroundProcess(r);
- p = NewPack();
- OutRpcClientConnect(p, connect);
- ret = RpcCall(r->Rpc, "Disconnect", p);
- if (RpcIsOk(ret) == false)
- {
- err = RpcGetError(ret);
- }
- FreePack(ret);
- return err;
- }
- // Get the account status
- UINT CcGetAccountStatus(REMOTE_CLIENT *r, RPC_CLIENT_GET_CONNECTION_STATUS *st)
- {
- PACK *ret, *p;
- UINT err = 0;
- // Validate arguments
- if (r == NULL || st == NULL)
- {
- return ERR_INTERNAL_ERROR;
- }
- p = NewPack();
- OutRpcClientGetConnectionStatus(p, st);
- ret = RpcCall(r->Rpc, "GetAccountStatus", p);
- if (RpcIsOk(ret))
- {
- InRpcClientGetConnectionStatus(st, ret);
- }
- else
- {
- err = RpcGetError(ret);
- }
- FreePack(ret);
- return err;
- }
- // Client service sends a notification to the connection manager
- void CiNotify(CLIENT *c)
- {
- CiNotifyInternal(c);
- }
- void CiNotifyInternal(CLIENT *c)
- {
- // Validate arguments
- if (c == NULL)
- {
- return;
- }
- // Set all the notification event
- LockList(c->NotifyCancelList);
- {
- UINT i;
- for (i = 0;i < LIST_NUM(c->NotifyCancelList);i++)
- {
- CANCEL *cancel = LIST_DATA(c->NotifyCancelList, i);
- Cancel(cancel);
- }
- }
- UnlockList(c->NotifyCancelList);
- }
- // Release the RPC_CLIENT_ENUM_ACCOUNT
- void CiFreeClientEnumAccount(RPC_CLIENT_ENUM_ACCOUNT *a)
- {
- UINT i;
- // Validate arguments
- if (a == NULL)
- {
- return;
- }
- for (i = 0;i < a->NumItem;i++)
- {
- RPC_CLIENT_ENUM_ACCOUNT_ITEM *e = a->Items[i];
- Free(e);
- }
- Free(a->Items);
- }
- // Thread to save the configuration file periodically
- void CiSaverThread(THREAD *t, void *param)
- {
- CLIENT *c = (CLIENT *)param;
- // Validate arguments
- if (t == NULL || param == NULL)
- {
- return;
- }
- NoticeThreadInit(t);
- // Wait for a certain period of time
- while (c->Halt == false)
- {
- Wait(c->SaverHalter, CLIENT_SAVER_INTERVAL);
- // Save
- CiSaveConfigurationFile(c);
- }
- }
- // Initialize the Saver
- void CiInitSaver(CLIENT *c)
- {
- // Validate arguments
- if (c == NULL)
- {
- return;
- }
- c->SaverHalter = NewEvent();
- c->SaverThread = NewThread(CiSaverThread, c);
- WaitThreadInit(c->SaverThread);
- }
- // Release the Saver
- void CiFreeSaver(CLIENT *c)
- {
- // Validate arguments
- if (c == NULL)
- {
- return;
- }
- c->Halt = true;
- Set(c->SaverHalter);
- WaitThread(c->SaverThread, INFINITE);
- ReleaseThread(c->SaverThread);
- ReleaseEvent(c->SaverHalter);
- }
- // CM_SETTING
- void InRpcCmSetting(CM_SETTING *c, PACK *p)
- {
- // Validate arguments
- if (c == NULL || p == NULL)
- {
- return;
- }
- Zero(c, sizeof(CM_SETTING));
- c->EasyMode = PackGetBool(p, "EasyMode");
- c->LockMode = PackGetBool(p, "LockMode");
- PackGetData2(p, "HashedPassword", c->HashedPassword, sizeof(c->HashedPassword));
- }
- void OutRpcCmSetting(PACK *p, CM_SETTING *c)
- {
- // Validate arguments
- if (c == NULL || p == NULL)
- {
- return;
- }
- PackAddBool(p, "EasyMode", c->EasyMode);
- PackAddBool(p, "LockMode", c->LockMode);
- PackAddData(p, "HashedPassword", c->HashedPassword, sizeof(c->HashedPassword));
- }
- // CLIENT_CONFIG
- void InRpcClientConfig(CLIENT_CONFIG *c, PACK *p)
- {
- // Validate arguments
- if (c == NULL || p == NULL)
- {
- return;
- }
- Zero(c, sizeof(CLIENT_CONFIG));
- c->UseKeepConnect = PackGetInt(p, "UseKeepConnect") == 0 ? false : true;
- c->KeepConnectPort = PackGetInt(p, "KeepConnectPort");
- c->KeepConnectProtocol = PackGetInt(p, "KeepConnectProtocol");
- c->KeepConnectInterval = PackGetInt(p, "KeepConnectInterval");
- c->AllowRemoteConfig = PackGetInt(p, "AllowRemoteConfig") == 0 ? false : true;
- PackGetStr(p, "KeepConnectHost", c->KeepConnectHost, sizeof(c->KeepConnectHost));
- }
- void OutRpcClientConfig(PACK *p, CLIENT_CONFIG *c)
- {
- // Validate arguments
- if (c == NULL || p == NULL)
- {
- return;
- }
- PackAddInt(p, "UseKeepConnect", c->UseKeepConnect);
- PackAddInt(p, "KeepConnectPort", c->KeepConnectPort);
- PackAddInt(p, "KeepConnectProtocol", c->KeepConnectProtocol);
- PackAddInt(p, "KeepConnectInterval", c->KeepConnectInterval);
- PackAddInt(p, "AllowRemoteConfig", c->AllowRemoteConfig);
- PackAddStr(p, "KeepConnectHost", c->KeepConnectHost);
- }
- // RPC_CLIENT_VERSION
- void InRpcClientVersion(RPC_CLIENT_VERSION *ver, PACK *p)
- {
- // Validate arguments
- if (ver == NULL || p == NULL)
- {
- return;
- }
- Zero(ver, sizeof(RPC_CLIENT_VERSION));
- PackGetStr(p, "ClientProductName", ver->ClientProductName, sizeof(ver->ClientProductName));
- PackGetStr(p, "ClientVersionString", ver->ClientVersionString, sizeof(ver->ClientVersionString));
- PackGetStr(p, "ClientBuildInfoString", ver->ClientBuildInfoString, sizeof(ver->ClientBuildInfoString));
- ver->ClientVerInt = PackGetInt(p, "ClientVerInt");
- ver->ClientBuildInt = PackGetInt(p, "ClientBuildInt");
- ver->ProcessId = PackGetInt(p, "ProcessId");
- ver->OsType = PackGetInt(p, "OsType");
- ver->IsVLanNameRegulated = PackGetBool(p, "IsVLanNameRegulated");
- ver->IsVgcSupported = PackGetBool(p, "IsVgcSupported");
- ver->ShowVgcLink = PackGetBool(p, "ShowVgcLink");
- PackGetStr(p, "ClientId", ver->ClientId, sizeof(ver->ClientId));
- }
- void OutRpcClientVersion(PACK *p, RPC_CLIENT_VERSION *ver)
- {
- // Validate arguments
- if (ver == NULL || p == NULL)
- {
- return;
- }
- PackAddStr(p, "ClientProductName", ver->ClientProductName);
- PackAddStr(p, "ClientVersionString", ver->ClientVersionString);
- PackAddStr(p, "ClientBuildInfoString", ver->ClientBuildInfoString);
- PackAddInt(p, "ClientVerInt", ver->ClientVerInt);
- PackAddInt(p, "ClientBuildInt", ver->ClientBuildInt);
- PackAddInt(p, "ProcessId", ver->ProcessId);
- PackAddInt(p, "OsType", ver->OsType);
- PackAddBool(p, "IsVLanNameRegulated", ver->IsVLanNameRegulated);
- PackAddBool(p, "IsVgcSupported", ver->IsVgcSupported);
- PackAddBool(p, "ShowVgcLink", ver->ShowVgcLink);
- PackAddStr(p, "ClientId", ver->ClientId);
- }
- // RPC_CLIENT_PASSWORD
- void InRpcClientPassword(RPC_CLIENT_PASSWORD *pw, PACK *p)
- {
- // Validate arguments
- if (pw == NULL || p == NULL)
- {
- return;
- }
- Zero(pw, sizeof(RPC_CLIENT_PASSWORD));
- PackGetStr(p, "Password", pw->Password, sizeof(pw->Password));
- pw->PasswordRemoteOnly = PackGetInt(p, "PasswordRemoteOnly");
- }
- void OutRpcClientPassword(PACK *p, RPC_CLIENT_PASSWORD *pw)
- {
- // Validate arguments
- if (pw == NULL || p == NULL)
- {
- return;
- }
- PackAddStr(p, "Password", pw->Password);
- PackAddInt(p, "PasswordRemoteOnly", pw->PasswordRemoteOnly);
- }
- // RPC_CLIENT_PASSWORD_SETTING
- void InRpcClientPasswordSetting(RPC_CLIENT_PASSWORD_SETTING *a, PACK *p)
- {
- // Validate arguments
- if (a == NULL || p == NULL)
- {
- return;
- }
- Zero(a, sizeof(RPC_CLIENT_PASSWORD_SETTING));
- a->IsPasswordPresented = PackGetInt(p, "IsPasswordPresented") == 0 ? false : true;
- a->PasswordRemoteOnly = PackGetInt(p, "PasswordRemoteOnly") == 0 ? false : true;
- }
- void OutRpcClientPasswordSetting(PACK *p, RPC_CLIENT_PASSWORD_SETTING *a)
- {
- // Validate arguments
- if (a == NULL || p == NULL)
- {
- return;
- }
- PackAddInt(p, "IsPasswordPresented", a->IsPasswordPresented);
- PackAddInt(p, "PasswordRemoteOnly", a->PasswordRemoteOnly);
- }
- // RPC_CLIENT_ENUM_CA
- void InRpcClientEnumCa(RPC_CLIENT_ENUM_CA *e, PACK *p)
- {
- UINT i;
- // Validate arguments
- if (e == NULL || p == NULL)
- {
- return;
- }
- Zero(e, sizeof(RPC_CLIENT_ENUM_CA));
- e->NumItem = PackGetNum(p, "NumItem");
- e->Items = ZeroMalloc(sizeof(RPC_CLIENT_ENUM_CA_ITEM *) * e->NumItem);
- for (i = 0;i < e->NumItem;i++)
- {
- RPC_CLIENT_ENUM_CA_ITEM *item = ZeroMalloc(sizeof(RPC_CLIENT_ENUM_CA_ITEM));
- e->Items[i] = item;
- item->Key = PackGetIntEx(p, "Key", i);
- PackGetUniStrEx(p, "SubjectName", item->SubjectName, sizeof(item->SubjectName), i);
- PackGetUniStrEx(p, "IssuerName", item->IssuerName, sizeof(item->IssuerName), i);
- item->Expires = PackGetInt64Ex(p, "Expires", i);
- }
- }
- void OutRpcClientEnumCa(PACK *p, RPC_CLIENT_ENUM_CA *e)
- {
- UINT i;
- // Validate arguments
- if (e == NULL || p == NULL)
- {
- return;
- }
- PackAddNum(p, "NumItem", e->NumItem);
- for (i = 0;i < e->NumItem;i++)
- {
- RPC_CLIENT_ENUM_CA_ITEM *item = e->Items[i];
- PackAddIntEx(p, "Key", item->Key, i, e->NumItem);
- PackAddUniStrEx(p, "SubjectName", item->SubjectName, i, e->NumItem);
- PackAddUniStrEx(p, "IssuerName", item->IssuerName, i, e->NumItem);
- PackAddInt64Ex(p, "Expires", item->Expires, i, e->NumItem);
- }
- }
- // RPC_GET_ISSUER
- void InRpcGetIssuer(RPC_GET_ISSUER *c, PACK *p)
- {
- BUF *b;
- // Validate arguments
- if (c == NULL || p == NULL)
- {
- return;
- }
- Zero(c, sizeof(RPC_GET_ISSUER));
- b = PackGetBuf(p, "x");
- if (b != NULL)
- {
- if (c->x != NULL)
- {
- FreeX(c->x);
- }
- c->x = BufToX(b, false);
- FreeBuf(b);
- }
- b = PackGetBuf(p, "issuer_x");
- if (b != NULL)
- {
- c->issuer_x = BufToX(b, false);
- FreeBuf(b);
- }
- }
- void OutRpcGetIssuer(PACK *p, RPC_GET_ISSUER *c)
- {
- BUF *b;
- // Validate arguments
- if (p == NULL || c == NULL)
- {
- return;
- }
- if (c->x != NULL)
- {
- b = XToBuf(c->x, false);
- PackAddBuf(p, "x", b);
- FreeBuf(b);
- }
- if (c->issuer_x != NULL)
- {
- b = XToBuf(c->issuer_x, false);
- PackAddBuf(p, "issuer_x", b);
- FreeBuf(b);
- }
- }
- // TRAFFIC_EX
- void InRpcTrafficEx(TRAFFIC *t, PACK *p, UINT i)
- {
- // Validate arguments
- if (t == NULL || p == NULL)
- {
- return;
- }
- Zero(t, sizeof(TRAFFIC));
- t->Recv.BroadcastBytes = PackGetInt64Ex(p, "Ex.Recv.BroadcastBytes", i);
- t->Recv.BroadcastCount = PackGetInt64Ex(p, "Ex.Recv.BroadcastCount", i);
- t->Recv.UnicastBytes = PackGetInt64Ex(p, "Ex.Recv.UnicastBytes", i);
- t->Recv.UnicastCount = PackGetInt64Ex(p, "Ex.Recv.UnicastCount", i);
- t->Send.BroadcastBytes = PackGetInt64Ex(p, "Ex.Send.BroadcastBytes", i);
- t->Send.BroadcastCount = PackGetInt64Ex(p, "Ex.Send.BroadcastCount", i);
- t->Send.UnicastBytes = PackGetInt64Ex(p, "Ex.Send.UnicastBytes", i);
- t->Send.UnicastCount = PackGetInt64Ex(p, "Ex.Send.UnicastCount", i);
- }
- void OutRpcTrafficEx(TRAFFIC *t, PACK *p, UINT i, UINT num)
- {
- // Validate arguments
- if (t == NULL || p == NULL)
- {
- return;
- }
- PackAddInt64Ex(p, "Ex.Recv.BroadcastBytes", t->Recv.BroadcastBytes, i, num);
- PackAddInt64Ex(p, "Ex.Recv.BroadcastCount", t->Recv.BroadcastCount, i, num);
- PackAddInt64Ex(p, "Ex.Recv.UnicastBytes", t->Recv.UnicastBytes, i, num);
- PackAddInt64Ex(p, "Ex.Recv.UnicastCount", t->Recv.UnicastCount, i, num);
- PackAddInt64Ex(p, "Ex.Send.BroadcastBytes", t->Send.BroadcastBytes, i, num);
- PackAddInt64Ex(p, "Ex.Send.BroadcastCount", t->Send.BroadcastCount, i, num);
- PackAddInt64Ex(p, "Ex.Send.UnicastBytes", t->Send.UnicastBytes, i, num);
- PackAddInt64Ex(p, "Ex.Send.UnicastCount", t->Send.UnicastCount, i, num);
- }
- // TRAFFIC
- void InRpcTraffic(TRAFFIC *t, PACK *p)
- {
- // Validate arguments
- if (t == NULL || p == NULL)
- {
- return;
- }
- Zero(t, sizeof(TRAFFIC));
- t->Recv.BroadcastBytes = PackGetInt64(p, "Recv.BroadcastBytes");
- t->Recv.BroadcastCount = PackGetInt64(p, "Recv.BroadcastCount");
- t->Recv.UnicastBytes = PackGetInt64(p, "Recv.UnicastBytes");
- t->Recv.UnicastCount = PackGetInt64(p, "Recv.UnicastCount");
- t->Send.BroadcastBytes = PackGetInt64(p, "Send.BroadcastBytes");
- t->Send.BroadcastCount = PackGetInt64(p, "Send.BroadcastCount");
- t->Send.UnicastBytes = PackGetInt64(p, "Send.UnicastBytes");
- t->Send.UnicastCount = PackGetInt64(p, "Send.UnicastCount");
- }
- void OutRpcTraffic(PACK *p, TRAFFIC *t)
- {
- // Validate arguments
- if (t == NULL || p == NULL)
- {
- return;
- }
- PackAddInt64(p, "Recv.BroadcastBytes", t->Recv.BroadcastBytes);
- PackAddInt64(p, "Recv.BroadcastCount", t->Recv.BroadcastCount);
- PackAddInt64(p, "Recv.UnicastBytes", t->Recv.UnicastBytes);
- PackAddInt64(p, "Recv.UnicastCount", t->Recv.UnicastCount);
- PackAddInt64(p, "Send.BroadcastBytes", t->Send.BroadcastBytes);
- PackAddInt64(p, "Send.BroadcastCount", t->Send.BroadcastCount);
- PackAddInt64(p, "Send.UnicastBytes", t->Send.UnicastBytes);
- PackAddInt64(p, "Send.UnicastCount", t->Send.UnicastCount);
- }
- // RPC_CERT
- void InRpcCert(RPC_CERT *c, PACK *p)
- {
- BUF *b;
- // Validate arguments
- if (c == NULL || p == NULL)
- {
- return;
- }
- Zero(c, sizeof(RPC_CERT));
- b = PackGetBuf(p, "x");
- if (b == NULL)
- {
- return;
- }
- c->x = BufToX(b, false);
- FreeBuf(b);
- }
- void OutRpcCert(PACK *p, RPC_CERT *c)
- {
- BUF *b;
- // Validate arguments
- if (p == NULL || c == NULL)
- {
- return;
- }
- if (c->x != NULL)
- {
- b = XToBuf(c->x, false);
- PackAddBuf(p, "x", b);
- FreeBuf(b);
- }
- }
- // RPC_CLIENT_DELETE_CA
- void InRpcClientDeleteCa(RPC_CLIENT_DELETE_CA *c, PACK *p)
- {
- // Validate arguments
- if (c == NULL || p == NULL)
- {
- return;
- }
- Zero(c, sizeof(RPC_CLIENT_DELETE_CA));
- c->Key = PackGetInt(p, "Key");
- }
- void OutRpcClientDeleteCa(PACK *p, RPC_CLIENT_DELETE_CA *c)
- {
- // Validate arguments
- if (c == NULL || p == NULL)
- {
- return;
- }
- PackAddInt(p, "Key", c->Key);
- }
- // RPC_GET_CA
- void InRpcGetCa(RPC_GET_CA *c, PACK *p)
- {
- BUF *b;
- // Validate arguments
- if (c == NULL || p == NULL)
- {
- return;
- }
- Zero(c, sizeof(RPC_GET_CA));
- c->Key = PackGetInt(p, "Key");
- b = PackGetBuf(p, "x");
- if (b != NULL)
- {
- c->x = BufToX(b, false);
- FreeBuf(b);
- }
- }
- void OutRpcGetCa(PACK *p, RPC_GET_CA *c)
- {
- // Validate arguments
- if (c == NULL || p == NULL)
- {
- return;
- }
- PackAddInt(p, "Key", c->Key);
- if (c->x != NULL)
- {
- BUF *b = XToBuf(c->x, false);
- PackAddBuf(p, "x", b);
- FreeBuf(b);
- }
- }
- // RPC_CLIENT_ENUM_SECURE
- void InRpcClientEnumSecure(RPC_CLIENT_ENUM_SECURE *e, PACK *p)
- {
- UINT i;
- // Validate arguments
- if (e == NULL || p == NULL)
- {
- return;
- }
- Zero(e, sizeof(RPC_CLIENT_ENUM_SECURE));
- e->NumItem = PackGetNum(p, "NumItem");
- e->Items = ZeroMalloc(sizeof(RPC_CLIENT_ENUM_SECURE_ITEM *) * e->NumItem);
- for (i = 0;i < e->NumItem;i++)
- {
- RPC_CLIENT_ENUM_SECURE_ITEM *item = e->Items[i] = ZeroMalloc(sizeof(RPC_CLIENT_ENUM_SECURE_ITEM));
- item->DeviceId = PackGetIntEx(p, "DeviceId", i);
- item->Type = PackGetIntEx(p, "Type", i);
- PackGetStrEx(p, "DeviceName", item->DeviceName, sizeof(item->DeviceName), i);
- PackGetStrEx(p, "Manufacturer", item->Manufacturer, sizeof(item->Manufacturer), i);
- }
- }
- void OutRpcClientEnumSecure(PACK *p, RPC_CLIENT_ENUM_SECURE *e)
- {
- UINT i;
- // Validate arguments
- if (e == NULL || p == NULL)
- {
- return;
- }
- PackAddNum(p, "NumItem", e->NumItem);
- for (i = 0;i < e->NumItem;i++)
- {
- RPC_CLIENT_ENUM_SECURE_ITEM *item = e->Items[i];
- PackAddIntEx(p, "DeviceId", item->DeviceId, i, e->NumItem);
- PackAddIntEx(p, "Type", item->Type, i, e->NumItem);
- PackAddStrEx(p, "DeviceName", item->DeviceName, i, e->NumItem);
- PackAddStrEx(p, "Manufacturer", item->Manufacturer, i, e->NumItem);
- }
- }
- // RPC_USE_SECURE
- void InRpcUseSecure(RPC_USE_SECURE *u, PACK *p)
- {
- // Validate arguments
- if (u == NULL || p == NULL)
- {
- return;
- }
- Zero(u, sizeof(RPC_USE_SECURE));
- u->DeviceId = PackGetInt(p, "DeviceId");
- }
- void OutRpcUseSecure(PACK *p, RPC_USE_SECURE *u)
- {
- // Validate arguments
- if (u == NULL || p == NULL)
- {
- return;
- }
- PackAddInt(p, "DeviceId", u->DeviceId);
- }
- // Release the RPC_ENUM_OBJECT_IN_SECURE
- void CiFreeEnumObjectInSecure(RPC_ENUM_OBJECT_IN_SECURE *a)
- {
- UINT i;
- // Validate arguments
- if (a == NULL)
- {
- return;
- }
- for (i = 0;i < a->NumItem;i++)
- {
- Free(a->ItemName[i]);
- }
- Free(a->ItemName);
- Free(a->ItemType);
- }
- // RPC_ENUM_OBJECT_IN_SECURE
- void InRpcEnumObjectInSecure(RPC_ENUM_OBJECT_IN_SECURE *e, PACK *p)
- {
- UINT i;
- // Validate arguments
- if (e == NULL || p == NULL)
- {
- return;
- }
- Zero(e, sizeof(RPC_ENUM_OBJECT_IN_SECURE));
- e->NumItem = PackGetNum(p, "NumItem");
- e->hWnd = PackGetInt(p, "hWnd");
- e->ItemName = ZeroMalloc(sizeof(char *) * e->NumItem);
- e->ItemType = ZeroMalloc(sizeof(bool) * e->NumItem);
- for (i = 0;i < e->NumItem;i++)
- {
- char name[MAX_SIZE];
- Zero(name, sizeof(name));
- PackGetStrEx(p, "ItemName", name, sizeof(name), i);
- e->ItemName[i] = CopyStr(name);
- e->ItemType[i] = PackGetIntEx(p, "ItemType", i) ? true : false;
- }
- }
- void OutRpcEnumObjectInSecure(PACK *p, RPC_ENUM_OBJECT_IN_SECURE *e)
- {
- UINT i;
- // Validate arguments
- if (e == NULL || p == NULL)
- {
- return;
- }
- PackAddNum(p, "NumItem", e->NumItem);
- PackAddInt(p, "hWnd", e->hWnd);
- for (i = 0;i < e->NumItem;i++)
- {
- PackAddStrEx(p, "ItemName", e->ItemName[i], i, e->NumItem);
- PackAddIntEx(p, "ItemType", e->ItemType[i], i, e->NumItem);
- }
- }
- // RPC_CLIENT_CREATE_VLAN
- void InRpcCreateVLan(RPC_CLIENT_CREATE_VLAN *v, PACK *p)
- {
- // Validate arguments
- if (v == NULL || p == NULL)
- {
- return;
- }
- Zero(v, sizeof(RPC_CLIENT_CREATE_VLAN));
- PackGetStr(p, "DeviceName", v->DeviceName, sizeof(v->DeviceName));
- }
- void OutRpcCreateVLan(PACK *p, RPC_CLIENT_CREATE_VLAN *v)
- {
- // Validate arguments
- if (v == NULL || p == NULL)
- {
- return;
- }
- PackAddStr(p, "DeviceName", v->DeviceName);
- }
- // RPC_CLIENT_GET_VLAN
- void InRpcClientGetVLan(RPC_CLIENT_GET_VLAN *v, PACK *p)
- {
- // Validate arguments
- if (v == NULL || p == NULL)
- {
- return;
- }
- Zero(v, sizeof(RPC_CLIENT_GET_VLAN));
- PackGetStr(p, "DeviceName", v->DeviceName, sizeof(v->DeviceName));
- v->Enabled = PackGetInt(p, "Enabled") ? true : false;
- PackGetStr(p, "MacAddress", v->MacAddress, sizeof(v->MacAddress));
- PackGetStr(p, "Version", v->Version, sizeof(v->Version));
- PackGetStr(p, "FileName", v->FileName, sizeof(v->FileName));
- PackGetStr(p, "Guid", v->Guid, sizeof(v->Guid));
- }
- void OutRpcClientGetVLan(PACK *p, RPC_CLIENT_GET_VLAN *v)
- {
- // Validate arguments
- if (v == NULL || p == NULL)
- {
- return;
- }
- PackAddStr(p, "DeviceName", v->DeviceName);
- PackAddInt(p, "Enabled", v->Enabled);
- PackAddStr(p, "MacAddress", v->MacAddress);
- PackAddStr(p, "Version", v->Version);
- PackAddStr(p, "FileName", v->FileName);
- PackAddStr(p, "Guid", v->Guid);
- }
- // RPC_CLIENT_SET_VLAN
- void InRpcClientSetVLan(RPC_CLIENT_SET_VLAN *v, PACK *p)
- {
- // Validate arguments
- if (v == NULL || p == NULL)
- {
- return;
- }
- Zero(v, sizeof(RPC_CLIENT_SET_VLAN));
- PackGetStr(p, "DeviceName", v->DeviceName, sizeof(v->DeviceName));
- PackGetStr(p, "MacAddress", v->MacAddress, sizeof(v->MacAddress));
- }
- void OutRpcClientSetVLan(PACK *p, RPC_CLIENT_SET_VLAN *v)
- {
- // Validate arguments
- if (v == NULL || p == NULL)
- {
- return;
- }
- PackAddStr(p, "DeviceName", v->DeviceName);
- PackAddStr(p, "MacAddress", v->MacAddress);
- }
- // RPC_CLIENT_ENUM_VLAN
- void InRpcClientEnumVLan(RPC_CLIENT_ENUM_VLAN *v, PACK *p)
- {
- UINT i;
- // Validate arguments
- if (v == NULL || p == NULL)
- {
- return;
- }
- Zero(v, sizeof(RPC_CLIENT_ENUM_VLAN));
- v->NumItem = PackGetNum(p, "NumItem");
- v->Items = ZeroMalloc(sizeof(RPC_CLIENT_ENUM_VLAN_ITEM *) * v->NumItem);
- for (i = 0;i < v->NumItem;i++)
- {
- RPC_CLIENT_ENUM_VLAN_ITEM *item = v->Items[i] =
- ZeroMalloc(sizeof(RPC_CLIENT_ENUM_VLAN_ITEM));
- PackGetStrEx(p, "DeviceName", item->DeviceName, sizeof(item->DeviceName), i);
- item->Enabled = PackGetIntEx(p, "Enabled", i) ? true : false;
- PackGetStrEx(p, "MacAddress", item->MacAddress, sizeof(item->MacAddress), i);
- PackGetStrEx(p, "Version", item->Version, sizeof(item->Version), i);
- }
- }
- void OutRpcClientEnumVLan(PACK *p, RPC_CLIENT_ENUM_VLAN *v)
- {
- UINT i;
- // Validate arguments
- if (v == NULL || p == NULL)
- {
- return;
- }
- PackAddNum(p, "NumItem", v->NumItem);
- for (i = 0;i < v->NumItem;i++)
- {
- RPC_CLIENT_ENUM_VLAN_ITEM *item = v->Items[i];
- PackAddStrEx(p, "DeviceName", item->DeviceName, i, v->NumItem);
- PackAddIntEx(p, "Enabled", item->Enabled, i, v->NumItem);
- PackAddStrEx(p, "MacAddress", item->MacAddress, i, v->NumItem);
- PackAddStrEx(p, "Version", item->Version, i, v->NumItem);
- }
- }
- // CLIENT_OPTION
- void InRpcClientOption(CLIENT_OPTION *c, PACK *p)
- {
- // Validate arguments
- if (c == NULL || p == NULL)
- {
- return;
- }
- Zero(c, sizeof(CLIENT_OPTION));
- PackGetUniStr(p, "AccountName", c->AccountName, sizeof(c->AccountName));
- PackGetStr(p, "Hostname", c->Hostname, sizeof(c->Hostname));
- c->Port = PackGetInt(p, "Port");
- c->PortUDP = PackGetInt(p, "PortUDP");
- c->ProxyType = PackGetInt(p, "ProxyType");
- c->ProxyPort = PackGetInt(p, "ProxyPort");
- c->NumRetry = PackGetInt(p, "NumRetry");
- c->RetryInterval = PackGetInt(p, "RetryInterval");
- c->MaxConnection = PackGetInt(p, "MaxConnection");
- c->AdditionalConnectionInterval = PackGetInt(p, "AdditionalConnectionInterval");
- c->ConnectionDisconnectSpan = PackGetInt(p, "ConnectionDisconnectSpan");
- c->HideStatusWindow = PackGetBool(p, "HideStatusWindow");
- c->HideNicInfoWindow = PackGetBool(p, "HideNicInfoWindow");
- c->DisableQoS = PackGetBool(p, "DisableQoS");
- PackGetStr(p, "ProxyName", c->ProxyName, sizeof(c->ProxyName));
- PackGetStr(p, "ProxyUsername", c->ProxyUsername, sizeof(c->ProxyUsername));
- PackGetStr(p, "ProxyPassword", c->ProxyPassword, sizeof(c->ProxyPassword));
- PackGetStr(p, "HubName", c->HubName, sizeof(c->HubName));
- PackGetStr(p, "DeviceName", c->DeviceName, sizeof(c->DeviceName));
- c->UseEncrypt = PackGetInt(p, "UseEncrypt") ? true : false;
- c->UseCompress = PackGetInt(p, "UseCompress") ? true : false;
- c->HalfConnection = PackGetInt(p, "HalfConnection") ? true : false;
- c->NoRoutingTracking = PackGetInt(p, "NoRoutingTracking") ? true : false;
- c->RequireMonitorMode = PackGetBool(p, "RequireMonitorMode");
- c->RequireBridgeRoutingMode = PackGetBool(p, "RequireBridgeRoutingMode");
- c->FromAdminPack = PackGetBool(p, "FromAdminPack");
- c->NoTls1 = PackGetBool(p, "NoTls1");
- c->NoUdpAcceleration = PackGetBool(p, "NoUdpAcceleration");
- PackGetData2(p, "HostUniqueKey", c->HostUniqueKey, SHA1_SIZE);
- }
- void OutRpcClientOption(PACK *p, CLIENT_OPTION *c)
- {
- // Validate arguments
- if (c == NULL || p == NULL)
- {
- return;
- }
- PackAddUniStr(p, "AccountName", c->AccountName);
- PackAddStr(p, "Hostname", c->Hostname);
- PackAddStr(p, "ProxyName", c->ProxyName);
- PackAddStr(p, "ProxyUsername", c->ProxyUsername);
- PackAddStr(p, "ProxyPassword", c->ProxyPassword);
- PackAddStr(p, "HubName", c->HubName);
- PackAddStr(p, "DeviceName", c->DeviceName);
- PackAddInt(p, "Port", c->Port);
- PackAddInt(p, "PortUDP", c->PortUDP);
- PackAddInt(p, "ProxyType", c->ProxyType);
- PackAddInt(p, "ProxyPort", c->ProxyPort);
- PackAddInt(p, "NumRetry", c->NumRetry);
- PackAddInt(p, "RetryInterval", c->RetryInterval);
- PackAddInt(p, "MaxConnection", c->MaxConnection);
- PackAddInt(p, "UseEncrypt", c->UseEncrypt);
- PackAddInt(p, "UseCompress", c->UseCompress);
- PackAddInt(p, "HalfConnection", c->HalfConnection);
- PackAddInt(p, "NoRoutingTracking", c->NoRoutingTracking);
- PackAddInt(p, "AdditionalConnectionInterval", c->AdditionalConnectionInterval);
- PackAddInt(p, "ConnectionDisconnectSpan", c->ConnectionDisconnectSpan);
- PackAddBool(p, "HideStatusWindow", c->HideStatusWindow);
- PackAddBool(p, "HideNicInfoWindow", c->HideNicInfoWindow);
- PackAddBool(p, "RequireMonitorMode", c->RequireMonitorMode);
- PackAddBool(p, "RequireBridgeRoutingMode", c->RequireBridgeRoutingMode);
- PackAddBool(p, "DisableQoS", c->DisableQoS);
- PackAddBool(p, "FromAdminPack", c->FromAdminPack);
- PackAddBool(p, "NoTls1", c->NoTls1);
- PackAddBool(p, "NoUdpAcceleration", c->NoUdpAcceleration);
- PackAddData(p, "HostUniqueKey", c->HostUniqueKey, SHA1_SIZE);
- }
- // CLIENT_AUTH
- void InRpcClientAuth(CLIENT_AUTH *c, PACK *p)
- {
- BUF *b;
- // Validate arguments
- if (c == NULL || p == NULL)
- {
- return;
- }
- Zero(c, sizeof(CLIENT_AUTH));
- c->AuthType = PackGetInt(p, "AuthType");
- PackGetStr(p, "Username", c->Username, sizeof(c->Username));
- switch (c->AuthType)
- {
- case CLIENT_AUTHTYPE_ANONYMOUS:
- break;
- case CLIENT_AUTHTYPE_PASSWORD:
- if (PackGetDataSize(p, "HashedPassword") == SHA1_SIZE)
- {
- PackGetData(p, "HashedPassword", c->HashedPassword);
- }
- break;
- case CLIENT_AUTHTYPE_PLAIN_PASSWORD:
- PackGetStr(p, "PlainPassword", c->PlainPassword, sizeof(c->PlainPassword));
- break;
- case CLIENT_AUTHTYPE_CERT:
- b = PackGetBuf(p, "ClientX");
- if (b != NULL)
- {
- c->ClientX = BufToX(b, false);
- FreeBuf(b);
- }
- b = PackGetBuf(p, "ClientK");
- if (b != NULL)
- {
- c->ClientK = BufToK(b, true, false, NULL);
- FreeBuf(b);
- }
- break;
- case CLIENT_AUTHTYPE_SECURE:
- PackGetStr(p, "SecurePublicCertName", c->SecurePublicCertName, sizeof(c->SecurePublicCertName));
- PackGetStr(p, "SecurePrivateKeyName", c->SecurePrivateKeyName, sizeof(c->SecurePrivateKeyName));
- break;
- }
- }
- void OutRpcClientAuth(PACK *p, CLIENT_AUTH *c)
- {
- BUF *b;
- // Validate arguments
- if (c == NULL || p == NULL)
- {
- return;
- }
- PackAddInt(p, "AuthType", c->AuthType);
- PackAddStr(p, "Username", c->Username);
- switch (c->AuthType)
- {
- case CLIENT_AUTHTYPE_ANONYMOUS:
- break;
- case CLIENT_AUTHTYPE_PASSWORD:
- PackAddData(p, "HashedPassword", c->HashedPassword, SHA1_SIZE);
- break;
- case CLIENT_AUTHTYPE_PLAIN_PASSWORD:
- PackAddStr(p, "PlainPassword", c->PlainPassword);
- break;
- case CLIENT_AUTHTYPE_CERT:
- b = XToBuf(c->ClientX, false);
- if (b != NULL)
- {
- PackAddBuf(p, "ClientX", b);
- FreeBuf(b);
- }
- b = KToBuf(c->ClientK, false, NULL);
- if (b != NULL)
- {
- PackAddBuf(p, "ClientK", b);
- FreeBuf(b);
- }
- break;
- case CLIENT_AUTHTYPE_SECURE:
- PackAddStr(p, "SecurePublicCertName", c->SecurePublicCertName);
- PackAddStr(p, "SecurePrivateKeyName", c->SecurePrivateKeyName);
- break;
- }
- }
- // RPC_CLIENT_CREATE_ACCOUNT
- void InRpcClientCreateAccount(RPC_CLIENT_CREATE_ACCOUNT *c, PACK *p)
- {
- BUF *b;
- // Validate arguments
- if (c == NULL || p == NULL)
- {
- return;
- }
- Zero(c, sizeof(RPC_CLIENT_CREATE_ACCOUNT));
- c->ClientOption = ZeroMalloc(sizeof(CLIENT_OPTION));
- c->ClientAuth = ZeroMalloc(sizeof(CLIENT_AUTH));
- InRpcClientOption(c->ClientOption, p);
- InRpcClientAuth(c->ClientAuth, p);
- c->StartupAccount = PackGetInt(p, "StartupAccount") ? true : false;
- c->CheckServerCert = PackGetInt(p, "CheckServerCert") ? true : false;
- b = PackGetBuf(p, "ServerCert");
- if (b != NULL)
- {
- c->ServerCert = BufToX(b, false);
- FreeBuf(b);
- }
- PackGetData2(p, "ShortcutKey", c->ShortcutKey, sizeof(c->ShortcutKey));
- }
- void OutRpcClientCreateAccount(PACK *p, RPC_CLIENT_CREATE_ACCOUNT *c)
- {
- BUF *b;
- // Validate arguments
- if (c == NULL || p == NULL)
- {
- return;
- }
- OutRpcClientOption(p, c->ClientOption);
- OutRpcClientAuth(p, c->ClientAuth);
- PackAddInt(p, "StartupAccount", c->StartupAccount);
- PackAddInt(p, "CheckServerCert", c->CheckServerCert);
- if (c->ServerCert != NULL)
- {
- b = XToBuf(c->ServerCert, false);
- if (b != NULL)
- {
- PackAddBuf(p, "ServerCert", b);
- FreeBuf(b);
- }
- }
- PackAddData(p, "ShortcutKey", c->ShortcutKey, sizeof(c->ShortcutKey));
- }
- // RPC_CLIENT_ENUM_ACCOUNT
- void InRpcClientEnumAccount(RPC_CLIENT_ENUM_ACCOUNT *e, PACK *p)
- {
- UINT i;
- // Validate arguments
- if (e == NULL || p == NULL)
- {
- return;
- }
- Zero(e, sizeof(RPC_CLIENT_ENUM_ACCOUNT));
- e->NumItem = PackGetNum(p, "NumItem");
- e->Items = ZeroMalloc(sizeof(RPC_CLIENT_ENUM_ACCOUNT_ITEM *) * e->NumItem);
- for (i = 0;i < e->NumItem;i++)
- {
- RPC_CLIENT_ENUM_ACCOUNT_ITEM *item = e->Items[i] =
- ZeroMalloc(sizeof(RPC_CLIENT_ENUM_ACCOUNT_ITEM));
- PackGetUniStrEx(p, "AccountName", item->AccountName, sizeof(item->AccountName), i);
- PackGetStrEx(p, "UserName", item->UserName, sizeof(item->UserName), i);
- PackGetStrEx(p, "ServerName", item->ServerName, sizeof(item->ServerName), i);
- PackGetStrEx(p, "ProxyName", item->ProxyName, sizeof(item->ProxyName), i);
- PackGetStrEx(p, "DeviceName", item->DeviceName, sizeof(item->DeviceName), i);
- item->ProxyType = PackGetIntEx(p, "ProxyType", i);
- item->Active = PackGetIntEx(p, "Active", i) ? true : false;
- item->StartupAccount = PackGetIntEx(p, "StartupAccount", i) ? true : false;
- item->Connected = PackGetBoolEx(p, "Connected", i);
- item->Port = PackGetIntEx(p, "Port", i);
- PackGetStrEx(p, "HubName", item->HubName, sizeof(item->HubName), i);
- item->CreateDateTime = PackGetInt64Ex(p, "CreateDateTime", i);
- item->UpdateDateTime = PackGetInt64Ex(p, "UpdateDateTime", i);
- item->LastConnectDateTime = PackGetInt64Ex(p, "LastConnectDateTime", i);
- }
- }
- void OutRpcClientEnumAccount(PACK *p, RPC_CLIENT_ENUM_ACCOUNT *e)
- {
- UINT i;
- // Validate arguments
- if (e == NULL || p == NULL)
- {
- return;
- }
- PackAddNum(p, "NumItem", e->NumItem);
- for (i = 0;i < e->NumItem;i++)
- {
- RPC_CLIENT_ENUM_ACCOUNT_ITEM *item = e->Items[i];
- PackAddUniStrEx(p, "AccountName", item->AccountName, i, e->NumItem);
- PackAddStrEx(p, "UserName", item->UserName, i, e->NumItem);
- PackAddStrEx(p, "ServerName", item->ServerName, i, e->NumItem);
- PackAddStrEx(p, "ProxyName", item->ProxyName, i, e->NumItem);
- PackAddStrEx(p, "DeviceName", item->DeviceName, i, e->NumItem);
- PackAddIntEx(p, "ProxyType", item->ProxyType, i, e->NumItem);
- PackAddIntEx(p, "Active", item->Active, i, e->NumItem);
- PackAddIntEx(p, "StartupAccount", item->StartupAccount, i, e->NumItem);
- PackAddBoolEx(p, "Connected", item->Connected, i, e->NumItem);
- PackAddIntEx(p, "Port", item->Port, i, e->NumItem);
- PackAddStrEx(p, "HubName", item->HubName, i, e->NumItem);
- PackAddInt64Ex(p, "CreateDateTime", item->CreateDateTime, i, e->NumItem);
- PackAddInt64Ex(p, "UpdateDateTime", item->UpdateDateTime, i, e->NumItem);
- PackAddInt64Ex(p, "LastConnectDateTime", item->LastConnectDateTime, i, e->NumItem);
- }
- }
- // RPC_CLIENT_DELETE_ACCOUNT
- void InRpcClientDeleteAccount(RPC_CLIENT_DELETE_ACCOUNT *a, PACK *p)
- {
- // Validate arguments
- if (a == NULL || p == NULL)
- {
- return;
- }
- Zero(a, sizeof(RPC_CLIENT_DELETE_ACCOUNT));
- PackGetUniStr(p, "AccountName", a->AccountName, sizeof(a->AccountName));
- }
- void OutRpcClientDeleteAccount(PACK *p, RPC_CLIENT_DELETE_ACCOUNT *a)
- {
- // Validate arguments
- if (a == NULL || p == NULL)
- {
- return;
- }
- PackAddUniStr(p, "AccountName", a->AccountName);
- }
- // RPC_RENAME_ACCOUNT
- void InRpcRenameAccount(RPC_RENAME_ACCOUNT *a, PACK *p)
- {
- // Validate arguments
- if (a == NULL || p == NULL)
- {
- return;
- }
- Zero(a, sizeof(RPC_RENAME_ACCOUNT));
- PackGetUniStr(p, "OldName", a->OldName, sizeof(a->OldName));
- PackGetUniStr(p, "NewName", a->NewName, sizeof(a->NewName));
- }
- void OutRpcRenameAccount(PACK *p, RPC_RENAME_ACCOUNT *a)
- {
- // Validate arguments
- if (a == NULL || p == NULL)
- {
- return;
- }
- PackAddUniStr(p, "OldName", a->OldName);
- PackAddUniStr(p, "NewName", a->NewName);
- }
- // RPC_CLIENT_GET_ACCOUNT
- void InRpcClientGetAccount(RPC_CLIENT_GET_ACCOUNT *c, PACK *p)
- {
- BUF *b;
- // Validate arguments
- if (c == NULL || p == NULL)
- {
- return;
- }
- Zero(c, sizeof(RPC_CLIENT_GET_ACCOUNT));
- c->ClientOption = ZeroMalloc(sizeof(CLIENT_OPTION));
- c->ClientAuth = ZeroMalloc(sizeof(CLIENT_AUTH));
- PackGetUniStr(p, "AccountName", c->AccountName, sizeof(c->AccountName));
- c->StartupAccount = PackGetInt(p, "StartupAccount") ? true : false;
- c->CheckServerCert = PackGetInt(p, "CheckServerCert") ? true : false;
- b = PackGetBuf(p, "ServerCert");
- if (b != NULL)
- {
- c->ServerCert = BufToX(b, false);
- FreeBuf(b);
- }
- InRpcClientOption(c->ClientOption, p);
- InRpcClientAuth(c->ClientAuth, p);
- c->CreateDateTime = PackGetInt64(p, "CreateDateTime");
- c->UpdateDateTime = PackGetInt64(p, "UpdateDateTime");
- c->LastConnectDateTime = PackGetInt64(p, "LastConnectDateTime");
- PackGetData2(p, "ShortcutKey", c->ShortcutKey, SHA1_SIZE);
- }
- void OutRpcClientGetAccount(PACK *p, RPC_CLIENT_GET_ACCOUNT *c)
- {
- BUF *b;
- // Validate arguments
- if (c == NULL || p == NULL)
- {
- return;
- }
- PackAddUniStr(p, "AccountName", c->AccountName);
- PackAddInt(p, "StartupAccount", c->StartupAccount);
- PackAddInt(p, "CheckServerCert", c->CheckServerCert);
- if (c->ServerCert != NULL)
- {
- b = XToBuf(c->ServerCert, false);
- if (b != NULL)
- {
- PackAddBuf(p, "ServerCert", b);
- FreeBuf(b);
- }
- }
- OutRpcClientOption(p, c->ClientOption);
- OutRpcClientAuth(p, c->ClientAuth);
- PackAddData(p, "ShortcutKey", c->ShortcutKey, SHA1_SIZE);
- PackAddInt64(p, "CreateDateTime", c->CreateDateTime);
- PackAddInt64(p, "UpdateDateTime", c->UpdateDateTime);
- PackAddInt64(p, "LastConnectDateTime", c->LastConnectDateTime);
- }
- // RPC_CLIENT_CONNECT
- void InRpcClientConnect(RPC_CLIENT_CONNECT *c, PACK *p)
- {
- // Validate arguments
- if (c == NULL || p == NULL)
- {
- return;
- }
- Zero(c, sizeof(RPC_CLIENT_CONNECT));
- PackGetUniStr(p, "AccountName", c->AccountName, sizeof(c->AccountName));
- }
- void OutRpcClientConnect(PACK *p, RPC_CLIENT_CONNECT *c)
- {
- // Validate arguments
- if (c == NULL || p == NULL)
- {
- return;
- }
- PackAddUniStr(p, "AccountName", c->AccountName);
- }
- // POLICY
- void InRpcPolicy(POLICY *o, PACK *p)
- {
- POLICY *pol;
- // Validate arguments
- if (o == NULL || p == NULL)
- {
- return;
- }
- pol = PackGetPolicy(p);
- Copy(o, pol, sizeof(POLICY));
- Free(pol);
- }
- void OutRpcPolicy(PACK *p, POLICY *o)
- {
- // Validate arguments
- if (o == NULL || p == NULL)
- {
- return;
- }
- PackAddPolicy(p, o);
- }
- // RPC_CLIENT_GET_CONNECTION_STATUS
- void InRpcClientGetConnectionStatus(RPC_CLIENT_GET_CONNECTION_STATUS *s, PACK *p)
- {
- BUF *b;
- // Validate arguments
- if (s == NULL || p == NULL)
- {
- return;
- }
- Zero(s, sizeof(RPC_CLIENT_GET_CONNECTION_STATUS));
- PackGetUniStr(p, "AccountName", s->AccountName, sizeof(s->AccountName));
- PackGetStr(p, "ServerName", s->ServerName, sizeof(s->ServerName));
- PackGetStr(p, "ServerProductName", s->ServerProductName, sizeof(s->ServerProductName));
- PackGetStr(p, "CipherName", s->CipherName, sizeof(s->CipherName));
- PackGetStr(p, "SessionName", s->SessionName, sizeof(s->SessionName));
- PackGetStr(p, "ConnectionName", s->ConnectionName, sizeof(s->ConnectionName));
- if (PackGetDataSize(p, "SessionKey") == SHA1_SIZE)
- {
- PackGetData(p, "SessionKey", s->SessionKey);
- }
- s->SessionStatus = PackGetInt(p, "SessionStatus");
- s->ServerPort = PackGetInt(p, "ServerPort");
- s->ServerProductVer = PackGetInt(p, "ServerProductVer");
- s->ServerProductBuild = PackGetInt(p, "ServerProductBuild");
- s->NumConnectionsEatablished = PackGetInt(p, "NumConnectionsEatablished");
- s->MaxTcpConnections = PackGetInt(p, "MaxTcpConnections");
- s->NumTcpConnections = PackGetInt(p, "NumTcpConnections");
- s->NumTcpConnectionsUpload = PackGetInt(p, "NumTcpConnectionsUpload");
- s->NumTcpConnectionsDownload = PackGetInt(p, "NumTcpConnectionsDownload");
- s->StartTime = PackGetInt64(p, "StartTime");
- s->FirstConnectionEstablisiedTime = PackGetInt64(p, "FirstConnectionEstablisiedTime");
- s->CurrentConnectionEstablishTime = PackGetInt64(p, "CurrentConnectionEstablishTime");
- s->TotalSendSize = PackGetInt64(p, "TotalSendSize");
- s->TotalRecvSize = PackGetInt64(p, "TotalRecvSize");
- s->TotalSendSizeReal = PackGetInt64(p, "TotalSendSizeReal");
- s->TotalRecvSizeReal = PackGetInt64(p, "TotalRecvSizeReal");
- s->Active = PackGetInt(p, "Active") ? true : false;
- s->Connected = PackGetInt(p, "Connected") ? true : false;
- s->HalfConnection = PackGetInt(p, "HalfConnection") ? true : false;
- s->QoS = PackGetInt(p, "QoS") ? true : false;
- s->UseEncrypt = PackGetInt(p, "UseEncrypt") ? true : false;
- s->UseCompress = PackGetInt(p, "UseCompress") ? true : false;
- s->IsRUDPSession = PackGetInt(p, "IsRUDPSession") ? true : false;
- PackGetStr(p, "UnderlayProtocol", s->UnderlayProtocol, sizeof(s->UnderlayProtocol));
- s->IsUdpAccelerationEnabled = PackGetInt(p, "IsUdpAccelerationEnabled") ? true : false;
- s->IsUsingUdpAcceleration = PackGetInt(p, "IsUsingUdpAcceleration") ? true : false;
- s->IsBridgeMode = PackGetBool(p, "IsBridgeMode");
- s->IsMonitorMode = PackGetBool(p, "IsMonitorMode");
- s->VLanId = PackGetInt(p, "VLanId");
- b = PackGetBuf(p, "ServerX");
- if (b != NULL)
- {
- s->ServerX = BufToX(b, false);
- FreeBuf(b);
- }
- b = PackGetBuf(p, "ClientX");
- if (b != NULL)
- {
- s->ClientX = BufToX(b, false);
- FreeBuf(b);
- }
- InRpcPolicy(&s->Policy, p);
- InRpcTraffic(&s->Traffic, p);
- }
- void OutRpcClientGetConnectionStatus(PACK *p, RPC_CLIENT_GET_CONNECTION_STATUS *c)
- {
- BUF *b;
- // Validate arguments
- if (p == NULL || c == NULL)
- {
- return;
- }
- PackAddUniStr(p, "AccountName", c->AccountName);
- PackAddStr(p, "ServerName", c->ServerName);
- PackAddStr(p, "ServerProductName", c->ServerProductName);
- PackAddStr(p, "CipherName", c->CipherName);
- PackAddStr(p, "SessionName", c->SessionName);
- PackAddStr(p, "ConnectionName", c->ConnectionName);
- PackAddData(p, "SessionKey", c->SessionKey, SHA1_SIZE);
- PackAddInt(p, "Active", c->Active);
- PackAddInt(p, "Connected", c->Connected);
- PackAddInt(p, "SessionStatus", c->SessionStatus);
- PackAddInt(p, "ServerPort", c->ServerPort);
- PackAddInt(p, "ServerProductVer", c->ServerProductVer);
- PackAddInt(p, "ServerProductBuild", c->ServerProductBuild);
- PackAddInt(p, "NumConnectionsEatablished", c->NumConnectionsEatablished);
- PackAddInt(p, "HalfConnection", c->HalfConnection);
- PackAddInt(p, "QoS", c->QoS);
- PackAddInt(p, "MaxTcpConnections", c->MaxTcpConnections);
- PackAddInt(p, "NumTcpConnections", c->NumTcpConnections);
- PackAddInt(p, "NumTcpConnectionsUpload", c->NumTcpConnectionsUpload);
- PackAddInt(p, "NumTcpConnectionsDownload", c->NumTcpConnectionsDownload);
- PackAddInt(p, "UseEncrypt", c->UseEncrypt);
- PackAddInt(p, "UseCompress", c->UseCompress);
- PackAddInt(p, "IsRUDPSession", c->IsRUDPSession);
- PackAddStr(p, "UnderlayProtocol", c->UnderlayProtocol);
- PackAddInt(p, "IsUdpAccelerationEnabled", c->IsUdpAccelerationEnabled);
- PackAddInt(p, "IsUsingUdpAcceleration", c->IsUsingUdpAcceleration);
- PackAddBool(p, "IsBridgeMode", c->IsBridgeMode);
- PackAddBool(p, "IsMonitorMode", c->IsMonitorMode);
- PackAddInt64(p, "StartTime", c->StartTime);
- PackAddInt64(p, "FirstConnectionEstablisiedTime", c->FirstConnectionEstablisiedTime);
- PackAddInt64(p, "CurrentConnectionEstablishTime", c->CurrentConnectionEstablishTime);
- PackAddInt64(p, "TotalSendSize", c->TotalSendSize);
- PackAddInt64(p, "TotalRecvSize", c->TotalRecvSize);
- PackAddInt64(p, "TotalSendSizeReal", c->TotalSendSizeReal);
- PackAddInt64(p, "TotalRecvSizeReal", c->TotalRecvSizeReal);
- PackAddInt(p, "VLanId", c->VLanId);
- OutRpcPolicy(p, &c->Policy);
- OutRpcTraffic(p, &c->Traffic);
- if (c->ServerX != NULL)
- {
- b = XToBuf(c->ServerX, false);
- PackAddBuf(p, "ServerX", b);
- FreeBuf(b);
- }
- if (c->ClientX != NULL)
- {
- b = XToBuf(c->ClientX, false);
- PackAddBuf(p, "ClientX", b);
- FreeBuf(b);
- }
- }
- void InRpcClientNotify(RPC_CLIENT_NOTIFY *n, PACK *p)
- {
- // Validate arguments
- if (n == NULL || p == NULL)
- {
- return;
- }
- Zero(n, sizeof(RPC_CLIENT_NOTIFY));
- n->NotifyCode = PackGetInt(p, "NotifyCode");
- }
- void OutRpcClientNotify(PACK *p, RPC_CLIENT_NOTIFY *n)
- {
- // Validate arguments
- if (n == NULL || p == NULL)
- {
- return;
- }
- PackAddInt(p, "NotifyCode", n->NotifyCode);
- }
- // Notification main
- void CiNotifyMain(CLIENT *c, SOCK *s)
- {
- CANCEL *cancel;
- // Validate arguments
- if (c == NULL || s == NULL)
- {
- return;
- }
- // Register a Cencel
- cancel = NewCancel();
- LockList(c->NotifyCancelList);
- {
- Add(c->NotifyCancelList, cancel);
- }
- UnlockList(c->NotifyCancelList);
- // Wait
- while (true)
- {
- char ch = '@';
- SOCKSET set;
- InitSockSet(&set);
- AddSockSet(&set, s);
- Select(&set, INFINITE, cancel, NULL);
- if (c->Halt)
- {
- // Abort
- break;
- }
- // 1 byte transmission
- if (Send(s, &ch, 1, false) == 0)
- {
- // Disconnected
- break;
- }
- }
- // Disconnect
- Disconnect(s);
- // Unregister the Cancel
- LockList(c->NotifyCancelList);
- {
- Delete(c->NotifyCancelList, cancel);
- }
- UnlockList(c->NotifyCancelList);
- ReleaseCancel(cancel);
- }
- // RPC acceptance code
- void CiRpcAccepted(CLIENT *c, SOCK *s)
- {
- UCHAR hashed_password[SHA1_SIZE];
- UINT rpc_mode;
- UINT retcode;
- RPC *rpc;
- // Validate arguments
- if (c == NULL || s == NULL)
- {
- return;
- }
- // Receive the RPC mode
- if (RecvAll(s, &rpc_mode, sizeof(UINT), false) == false)
- {
- return;
- }
- rpc_mode = Endian32(rpc_mode);
- if (rpc_mode == CLIENT_RPC_MODE_NOTIFY)
- {
- // Notification mode
- CiNotifyMain(c, s);
- return;
- }
- else if (rpc_mode == CLIENT_RPC_MODE_SHORTCUT || rpc_mode == CLIENT_RPC_MODE_SHORTCUT_DISCONNECT)
- {
- // Shortcut key received
- UCHAR key[SHA1_SIZE];
- UINT err = ERR_NO_ERROR;
- if (RecvAll(s, key, SHA1_SIZE, false))
- {
- UINT i;
- wchar_t title[MAX_ACCOUNT_NAME_LEN + 1];
- bool ok = false;
- // Connect to the specified setting
- LockList(c->AccountList);
- {
- for (i = 0;i < LIST_NUM(c->AccountList);i++)
- {
- ACCOUNT *a = LIST_DATA(c->AccountList, i);
- Lock(a->lock);
- {
- if (Cmp(a->ShortcutKey, key, SHA1_SIZE) == 0)
- {
- ok = true;
- UniStrCpy(title, sizeof(title), a->ClientOption->AccountName);
- }
- }
- Unlock(a->lock);
- }
- }
- UnlockList(c->AccountList);
- if (ok == false)
- {
- err = ERR_ACCOUNT_NOT_FOUND;
- }
- else
- {
- RPC_CLIENT_CONNECT t;
- Zero(&t, sizeof(t));
- UniStrCpy(t.AccountName, sizeof(t.AccountName), title);
- if (rpc_mode == CLIENT_RPC_MODE_SHORTCUT)
- {
- // Connect
- if (CtConnect(c, &t))
- {
- err = ERR_NO_ERROR;
- }
- else
- {
- err = c->Err;
- }
- }
- else
- {
- // Connect
- if (CtDisconnect(c, &t, false))
- {
- err = ERR_NO_ERROR;
- }
- else
- {
- err = c->Err;
- }
- }
- }
- err = Endian32(err);
- SendAll(s, &err, sizeof(UINT), false);
- RecvAll(s, &err, sizeof(UINT), false);
- }
- return;
- }
- // Password reception
- if (RecvAll(s, hashed_password, SHA1_SIZE, false) == false)
- {
- return;
- }
- retcode = 0;
- // Password comparison
- if (Cmp(hashed_password, c->EncryptedPassword, SHA1_SIZE) != 0)
- {
- retcode = 1;
- }
- if (c->PasswordRemoteOnly && s->RemoteIP.addr[0] == 127)
- {
- // If in a mode that requires a password only remote,
- // the password sent from localhost is considered to be always correct
- retcode = 0;
- }
- Lock(c->lock);
- {
- if (c->Config.AllowRemoteConfig == false)
- {
- // If the remote control is prohibited,
- // identify whether this connection is from remote
- if (s->RemoteIP.addr[0] != 127)
- {
- retcode = 2;
- }
- }
- }
- Unlock(c->lock);
- retcode = Endian32(retcode);
- // Error code transmission
- if (SendAll(s, &retcode, sizeof(UINT), false) == false)
- {
- return;
- }
- if (retcode != 0)
- {
- // Disconnect due to an error
- return;
- }
- // Create a RPC server
- rpc = StartRpcServer(s, CiRpcDispatch, c);
- // RPC server operation
- RpcServer(rpc);
- // Release the RPC server
- EndRpc(rpc);
- }
- // RPC acceptance thread
- void CiRpcAcceptThread(THREAD *thread, void *param)
- {
- CLIENT_RPC_CONNECTION *conn;
- CLIENT *c;
- SOCK *s;
- // Validate arguments
- if (thread == NULL || param == NULL)
- {
- return;
- }
- conn = (CLIENT_RPC_CONNECTION *)param;
- s = conn->Sock;
- c = conn->Client;
- AddRef(s->ref);
- // Add to the RPC connection list
- LockList(c->RpcConnectionList);
- {
- Add(c->RpcConnectionList, conn);
- }
- UnlockList(c->RpcConnectionList);
- NoticeThreadInit(thread);
- // Main process
- CiRpcAccepted(c, s);
- // Release from the connection list
- LockList(c->RpcConnectionList);
- {
- Delete(c->RpcConnectionList, conn);
- }
- UnlockList(c->RpcConnectionList);
- ReleaseSock(conn->Sock);
- ReleaseThread(conn->Thread);
- Free(conn);
- Disconnect(s);
- ReleaseSock(s);
- }
- // RPC server thread
- void CiRpcServerThread(THREAD *thread, void *param)
- {
- CLIENT *c;
- SOCK *listener;
- UINT i;
- LIST *thread_list;
- // Validate arguments
- if (thread == NULL || param == NULL)
- {
- return;
- }
- c = (CLIENT *)param;
- // RPC connection list
- c->RpcConnectionList = NewList(NULL);
- // Open the port
- listener = NULL;
- for (i = CLIENT_CONFIG_PORT;i < (CLIENT_CONFIG_PORT + 5);i++)
- {
- listener = Listen(i);
- if (listener != NULL)
- {
- break;
- }
- }
- if (listener == NULL)
- {
- // Error
- Alert(CEDAR_PRODUCT_STR " VPN Client RPC Port Open Failed.", CEDAR_CLIENT_STR);
- return;
- }
- #ifdef OS_WIN32
- MsRegWriteIntEx2(REG_LOCAL_MACHINE, CLIENT_WIN32_REGKEYNAME, CLIENT_WIN32_REGVALUE_PORT, i, false, true);
- MsRegWriteIntEx2(REG_LOCAL_MACHINE, CLIENT_WIN32_REGKEYNAME, CLIENT_WIN32_REGVALUE_PID, MsGetCurrentProcessId(), false, true);
- #endif // OS_WIN32
- c->RpcListener = listener;
- AddRef(listener->ref);
- NoticeThreadInit(thread);
- while (true)
- {
- // Wait for client connection
- CLIENT_RPC_CONNECTION *conn;
- SOCK *s = Accept(listener);
- if (s == NULL)
- {
- // Stop
- break;
- }
- // Create a client processing thread
- conn = ZeroMalloc(sizeof(CLIENT_RPC_CONNECTION));
- conn->Client = c;
- conn->Sock = s;
- AddRef(s->ref);
- conn->Thread = NewThread(CiRpcAcceptThread, (void *)conn);
- WaitThreadInit(conn->Thread);
- ReleaseSock(s);
- }
- // Release the listener
- ReleaseSock(listener);
- thread_list = NewListFast(NULL);
- // Set all the event notification
- LockList(c->NotifyCancelList);
- {
- UINT i;
- for (i = 0;i < LIST_NUM(c->NotifyCancelList);i++)
- {
- CANCEL *cancel = LIST_DATA(c->NotifyCancelList, i);
- Cancel(cancel);
- }
- }
- UnlockList(c->NotifyCancelList);
- // Disconnect all the connections of connected yet
- LockList(c->RpcConnectionList);
- {
- for (i = 0;i < LIST_NUM(c->RpcConnectionList);i++)
- {
- CLIENT_RPC_CONNECTION *cc = LIST_DATA(c->RpcConnectionList, i);
- AddRef(cc->Thread->ref);
- Add(thread_list, cc->Thread);
- Disconnect(cc->Sock);
- }
- }
- UnlockList(c->RpcConnectionList);
- for (i = 0;i < LIST_NUM(thread_list);i++)
- {
- THREAD *t = LIST_DATA(thread_list, i);
- WaitThread(t, INFINITE);
- ReleaseThread(t);
- }
- ReleaseList(c->RpcConnectionList);
- ReleaseList(thread_list);
- #ifdef OS_WIN32
- MsRegDeleteValueEx2(REG_LOCAL_MACHINE, CLIENT_WIN32_REGKEYNAME, CLIENT_WIN32_REGVALUE_PORT, false, true);
- MsRegDeleteValueEx2(REG_LOCAL_MACHINE, CLIENT_WIN32_REGKEYNAME, CLIENT_WIN32_REGVALUE_PID, false, true);
- #endif // OS_WIN32
- }
- // Start the Keep
- void CiInitKeep(CLIENT *c)
- {
- // Validate arguments
- if (c == NULL)
- {
- return;
- }
- c->Keep = StartKeep();
- // Apply settings
- if (c->Config.UseKeepConnect)
- {
- KEEP *k = c->Keep;
- Lock(k->lock);
- {
- StrCpy(k->ServerName, sizeof(k->ServerName), c->Config.KeepConnectHost);
- k->ServerPort = c->Config.KeepConnectPort;
- k->Interval = c->Config.KeepConnectInterval * 1000;
- k->UdpMode = (c->Config.KeepConnectProtocol == CONNECTION_UDP) ? true : false;
- k->Enable = true;
- }
- Unlock(k->lock);
- }
- }
- // Stop the Keep
- void CiFreeKeep(CLIENT *c)
- {
- // Validate arguments
- if (c == NULL)
- {
- return;
- }
- StopKeep(c->Keep);
- c->Keep = NULL;
- }
- // Start the RPC
- void CiStartRpcServer(CLIENT *c)
- {
- // Validate arguments
- if (c == NULL)
- {
- return;
- }
- c->RpcThread = NewThread(CiRpcServerThread, (void *)c);
- WaitThreadInit(c->RpcThread);
- }
- // Stop the RPC
- void CiStopRpcServer(CLIENT *c)
- {
- // Validate arguments
- if (c == NULL)
- {
- return;
- }
- Disconnect(c->RpcListener);
- ReleaseSock(c->RpcListener);
- WaitThread(c->RpcThread, INFINITE);
- ReleaseThread(c->RpcThread);
- }
- // Wait for the next notification
- bool CcWaitNotify(NOTIFY_CLIENT *n)
- {
- UCHAR c;
- // Validate arguments
- if (n == NULL)
- {
- return false;
- }
- // 1 character reception
- if (RecvAll(n->Sock, &c, 1, false) == false)
- {
- // Disconnected
- return false;
- }
- return true;
- }
- // Connect as a notification client
- NOTIFY_CLIENT *CcConnectNotify(REMOTE_CLIENT *rc)
- {
- NOTIFY_CLIENT *n;
- SOCK *s;
- char tmp[MAX_SIZE];
- bool rpc_mode = false;
- UINT port;
- // Validate arguments
- if (rc == NULL || rc->Rpc == NULL || rc->Rpc->Sock == NULL)
- {
- return NULL;
- }
- // Connect
- IPToStr(tmp, sizeof(tmp), &rc->Rpc->Sock->RemoteIP);
- port = rc->Rpc->Sock->RemotePort;
- s = Connect(tmp, port);
- if (s == NULL)
- {
- return NULL;
- }
- rpc_mode = Endian32(rpc_mode);
- if (SendAll(s, &rpc_mode, sizeof(rpc_mode), false) == false)
- {
- ReleaseSock(s);
- return NULL;
- }
- n = ZeroMalloc(sizeof(NOTIFY_CLIENT));
- n->Sock = s;
- return n;
- }
- // Stop the notification client
- void CcStopNotify(NOTIFY_CLIENT *n)
- {
- // Validate arguments
- if (n == NULL)
- {
- return;
- }
- Disconnect(n->Sock);
- }
- // Delete the notification client
- void CcDisconnectNotify(NOTIFY_CLIENT *n)
- {
- // Validate arguments
- if (n == NULL)
- {
- return;
- }
- // Disconnect
- Disconnect(n->Sock);
- ReleaseSock(n->Sock);
- // Memory release
- Free(n);
- }
- // Disconnect the remote connection
- void CcDisconnectRpc(REMOTE_CLIENT *rc)
- {
- // Validate arguments
- if (rc == NULL)
- {
- return;
- }
- RpcFree(rc->Rpc);
- Free(rc);
- }
- // Connect to the client to start the shortcut connection setting
- UINT CcShortcut(UCHAR *key)
- {
- UINT ret;
- // Validate arguments
- if (key == NULL)
- {
- return ERR_INVALID_PARAMETER;
- }
- CcConnectRpcEx("localhost", NULL, NULL, NULL, key, &ret, false, 0);
- return ret;
- }
- // Disconnect the connected shortcut connection
- UINT CcShortcutDisconnect(UCHAR *key)
- {
- UINT ret;
- // Validate arguments
- if (key == NULL)
- {
- return ERR_INVALID_PARAMETER;
- }
- CcConnectRpcEx("localhost", NULL, NULL, NULL, key, &ret, true, 0);
- return ret;
- }
- // Connect to the remote client
- REMOTE_CLIENT *CcConnectRpc(char *server_name, char *password, bool *bad_pass, bool *no_remote, UINT wait_retry)
- {
- return CcConnectRpcEx(server_name, password, bad_pass, no_remote, NULL, NULL, false, wait_retry);
- }
- 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)
- {
- SOCK *s = NULL;
- UINT i;
- UINT retcode;
- UINT rpc_mode = CLIENT_RPC_MODE_MANAGEMENT;
- RPC *rpc;
- REMOTE_CLIENT *ret;
- UCHAR hash_password[SHA1_SIZE];
- UINT port_start;
- UINT64 try_started = 0;
- bool ok;
- UINT reg_port = 0;
- UINT reg_pid = 0;
- // Validate arguments
- if (server_name == NULL)
- {
- return NULL;
- }
- if (password == NULL)
- {
- password = "";
- }
- if (key_error_code != NULL)
- {
- *key_error_code = ERR_NO_ERROR;
- }
- if (bad_pass != NULL)
- {
- *bad_pass = false;
- }
- if (no_remote != NULL)
- {
- *no_remote = false;
- }
- #ifdef OS_WIN32
- // read the current port number from the registry of the localhost
- if (StrCmpi(server_name, "localhost") == 0)
- {
- reg_port = MsRegReadIntEx2(REG_LOCAL_MACHINE, CLIENT_WIN32_REGKEYNAME, CLIENT_WIN32_REGVALUE_PORT, false, true);
- reg_pid = MsRegReadIntEx2(REG_LOCAL_MACHINE, CLIENT_WIN32_REGKEYNAME, CLIENT_WIN32_REGVALUE_PID, false, true);
- if (reg_pid != 0)
- {
- if (MsIsServiceRunning(GC_SVC_NAME_VPNCLIENT) == false)
- {
- reg_port = 0;
- }
- }
- else
- {
- reg_port = 0;
- }
- }
- #endif // OS_WIN32
- port_start = CLIENT_CONFIG_PORT - 1;
- if (reg_port != 0)
- {
- s = Connect(server_name, reg_port);
- if (s != NULL)
- {
- goto L_TRY;
- }
- }
- RETRY:
- port_start++;
- if (port_start >= (CLIENT_CONFIG_PORT + 5))
- {
- return NULL;
- }
- ok = false;
- while (true)
- {
- for (i = port_start;i < (CLIENT_CONFIG_PORT + 5);i++)
- {
- if (CheckTCPPort(server_name, i))
- {
- ok = true;
- break;
- }
- }
- if (ok)
- {
- break;
- }
- if (wait_retry == 0)
- {
- break;
- }
- if (try_started == 0)
- {
- try_started = Tick64();
- }
- if ((try_started + (UINT64)wait_retry) <= Tick64())
- {
- break;
- }
- }
- if (ok == false)
- {
- if (key_error_code)
- {
- *key_error_code = ERR_CONNECT_FAILED;
- }
- return NULL;
- }
- port_start = i;
- s = Connect(server_name, i);
- if (s == NULL)
- {
- if (key_error_code)
- {
- *key_error_code = ERR_CONNECT_FAILED;
- }
- goto RETRY;
- }
- L_TRY:
- SetTimeout(s, 10000);
- Hash(hash_password, password, StrLen(password), true);
- if (key != NULL)
- {
- if (shortcut_disconnect == false)
- {
- rpc_mode = CLIENT_RPC_MODE_SHORTCUT;
- }
- else
- {
- rpc_mode = CLIENT_RPC_MODE_SHORTCUT_DISCONNECT;
- }
- }
- rpc_mode = Endian32(rpc_mode);
- SendAdd(s, &rpc_mode, sizeof(UINT));
- if (key != NULL)
- {
- SendAdd(s, key, SHA1_SIZE);
- }
- else
- {
- SendAdd(s, hash_password, SHA1_SIZE);
- }
- if (SendNow(s, false) == false)
- {
- ReleaseSock(s);
- goto RETRY;
- }
- if (RecvAll(s, &retcode, sizeof(UINT), false) == false)
- {
- ReleaseSock(s);
- goto RETRY;
- }
- retcode = Endian32(retcode);
- if (retcode >= 1024)
- {
- ReleaseSock(s);
- goto RETRY;
- }
- if (key != NULL)
- {
- if (key_error_code)
- {
- *key_error_code = retcode;
- }
- SendAll(s, &retcode, sizeof(UINT), false);
- ReleaseSock(s);
- return NULL;
- }
- switch (retcode)
- {
- case 1:
- if (bad_pass != NULL)
- {
- *bad_pass = true;
- }
- break;
- case 2:
- if (no_remote != NULL)
- {
- *no_remote = true;
- }
- break;
- }
- if (retcode != 0)
- {
- ReleaseSock(s);
- return NULL;
- }
- SetTimeout(s, INFINITE);
- rpc = StartRpcClient(s, NULL);
- ReleaseSock(s);
- ret = ZeroMalloc(sizeof(REMOTE_CLIENT));
- ret->Rpc = rpc;
- rpc->Param = ret;
- if (ret != NULL)
- {
- RPC_CLIENT_VERSION t;
- Zero(&t, sizeof(t));
- CcGetClientVersion(ret, &t);
- ret->OsType = t.OsType;
- ret->Unix = OS_IS_UNIX(ret->OsType);
- ret->Win9x = OS_IS_WINDOWS_9X(ret->OsType);
- ret->IsVgcSupported = t.IsVgcSupported;
- ret->ShowVgcLink = t.ShowVgcLink;
- StrCpy(ret->ClientId, sizeof(ret->ClientId), t.ClientId);
- }
- return ret;
- }
- // Get a RPC_CLIENT_GET_CONNECTION_STATUS from the session
- void CiGetSessionStatus(RPC_CLIENT_GET_CONNECTION_STATUS *st, SESSION *s)
- {
- // Validate arguments
- if (st == NULL || s == NULL)
- {
- return;
- }
- Lock(s->lock);
- {
- // Operation flag
- st->Active = true;
- // Session status
- st->SessionStatus = s->ClientStatus;
- // Account name
- UniStrCpy(st->AccountName, sizeof(st->AccountName), s->ClientOption->AccountName);
- if (s->ClientStatus == CLIENT_STATUS_ESTABLISHED && s->Connection != NULL)
- {
- Lock(s->Connection->lock);
- {
- // Connected flag
- st->Connected = true;
- // Product name
- StrCpy(st->ServerProductName, sizeof(st->ServerProductName), s->Connection->ServerStr);
- // Version
- st->ServerProductVer = s->Connection->ServerVer;
- // Build Number
- st->ServerProductBuild = s->Connection->ServerBuild;
- // Server certificate
- st->ServerX = CloneX(s->Connection->ServerX);
- // Client certificate
- st->ClientX = CloneX(s->Connection->ClientX);
- // Connection completion time of this connection
- st->CurrentConnectionEstablishTime = TickToTime(s->CurrentConnectionEstablishTime);
- // Maximum number of the TCP connections
- st->MaxTcpConnections = s->MaxConnection;
- // Half-connection
- st->HalfConnection = s->HalfConnection;
- // VLAN
- st->VLanId = s->VLanId;
- // VoIP / QoS
- st->QoS = s->QoS;
- if (s->Connection->Protocol == CONNECTION_TCP)
- {
- UINT i;
- // Number of current TCP connections
- LockList(s->Connection->Tcp->TcpSockList);
- {
- st->NumTcpConnections = LIST_NUM(s->Connection->Tcp->TcpSockList);
- if (st->HalfConnection)
- {
- for (i = 0;i < st->NumTcpConnections;i++)
- {
- TCPSOCK *ts = LIST_DATA(s->Connection->Tcp->TcpSockList, i);
- if (ts->Direction & TCP_SERVER_TO_CLIENT)
- {
- st->NumTcpConnectionsDownload++;
- }
- else
- {
- st->NumTcpConnectionsUpload++;
- }
- }
- }
- }
- UnlockList(s->Connection->Tcp->TcpSockList);
- }
- // Use of encryption
- st->UseEncrypt = s->UseEncrypt;
- if (st->UseEncrypt)
- {
- StrCpy(st->CipherName, sizeof(st->CipherName), s->Connection->CipherName);
- }
- // Use of compression
- st->UseCompress = s->UseCompress;
- // R-UDP
- st->IsRUDPSession = s->IsRUDPSession;
- // Physical communication protocol
- StrCpy(st->UnderlayProtocol, sizeof(st->UnderlayProtocol), s->UnderlayProtocol);
- // UDP acceleration function
- st->IsUdpAccelerationEnabled = s->UseUdpAcceleration;
- st->IsUsingUdpAcceleration = s->IsUsingUdpAcceleration;
- // Session key
- Copy(st->SessionKey, s->SessionKey, SHA1_SIZE);
- // Policy
- Copy(&st->Policy, s->Policy, sizeof(POLICY));
- // Data size
- if (s->ServerMode == false)
- {
- st->TotalSendSize = s->TotalSendSize;
- st->TotalRecvSize = s->TotalRecvSize;
- st->TotalRecvSizeReal = s->TotalRecvSizeReal;
- st->TotalSendSizeReal = s->TotalSendSizeReal;
- }
- else
- {
- st->TotalSendSize = s->TotalRecvSize;
- st->TotalRecvSize = s->TotalSendSize;
- st->TotalRecvSizeReal = s->TotalSendSizeReal;
- st->TotalSendSizeReal = s->TotalRecvSizeReal;
- }
- // Session name
- StrCpy(st->SessionName, sizeof(st->SessionName), s->Name);
- // Connection name
- StrCpy(st->ConnectionName, sizeof(st->ConnectionName), s->Connection->Name);
- // Server name
- StrCpy(st->ServerName, sizeof(st->ServerName), s->Connection->ServerName);
- // Port number
- st->ServerPort = s->Connection->ServerPort;
- // Traffic data
- Lock(s->TrafficLock);
- {
- Copy(&st->Traffic, s->Traffic, sizeof(TRAFFIC));
- }
- Unlock(s->TrafficLock);
- st->IsBridgeMode = s->IsBridgeMode;
- st->IsMonitorMode = s->IsMonitorMode;
- }
- Unlock(s->Connection->lock);
- }
- // Connection start time
- st->StartTime = TickToTime(s->CreatedTime);
- // Connection completion time of the first connection
- st->FirstConnectionEstablisiedTime = TickToTime(s->FirstConnectionEstablisiedTime);
- // Number of connections have been established so far
- st->NumConnectionsEatablished = s->NumConnectionsEatablished;
- }
- Unlock(s->lock);
- }
- // Get the connection status
- bool CtGetAccountStatus(CLIENT *c, RPC_CLIENT_GET_CONNECTION_STATUS *st)
- {
- // Validate arguments
- if (c == NULL || st == NULL)
- {
- return false;
- }
- LockList(c->AccountList);
- {
- ACCOUNT t, *r;
- // Search for account
- t.ClientOption = ZeroMalloc(sizeof(CLIENT_OPTION));
- UniStrCpy(t.ClientOption->AccountName, sizeof(t.ClientOption->AccountName), st->AccountName);
- r = Search(c->AccountList, &t);
- if (r == NULL)
- {
- // Specified account is not found
- UnlockList(c->AccountList);
- Free(t.ClientOption);
- CiSetError(c, ERR_ACCOUNT_NOT_FOUND);
- return false;
- }
- Free(t.ClientOption);
- Lock(r->lock);
- {
- Zero(st, sizeof(RPC_CLIENT_GET_CONNECTION_STATUS));
- if (r->ClientSession != NULL)
- {
- SESSION *s = r->ClientSession;
- CiGetSessionStatus(st, s);
- }
- }
- Unlock(r->lock);
- }
- UnlockList(c->AccountList);
- return true;
- }
- // Release the connection status
- void CiFreeClientGetConnectionStatus(RPC_CLIENT_GET_CONNECTION_STATUS *st)
- {
- // Validate arguments
- if (st == NULL)
- {
- return;
- }
- if (st->ServerX != NULL)
- {
- FreeX(st->ServerX);
- }
- if (st->ClientX != NULL)
- {
- FreeX(st->ClientX);
- }
- }
- // Verification procedure of the server certificate
- bool CiCheckCertProc(SESSION *s, CONNECTION *c, X *server_x, bool *expired)
- {
- #ifdef OS_WIN32
- ACCOUNT *a;
- X *old_x = NULL;
- UI_CHECKCERT dlg;
- // Validate arguments
- if (s == NULL || c == NULL || server_x == NULL)
- {
- return false;
- }
- if (expired != NULL)
- {
- *expired = false;
- }
- Zero(&dlg, sizeof(dlg));
- a = s->Account;
- if (a == NULL)
- {
- return false;
- }
- Lock(a->lock);
- {
- if (a->CheckServerCert == false)
- {
- // Not to validate the server certificate
- Unlock(a->lock);
- return true;
- }
- if (a->ServerCert != NULL)
- {
- old_x = CloneX(a->ServerCert);
- }
- }
- Unlock(a->lock);
- if (CheckXDateNow(server_x) == false)
- {
- // Expired
- if (old_x != NULL)
- {
- FreeX(old_x);
- }
- if (expired != NULL)
- {
- *expired = true;
- }
- return false;
- }
- if (old_x != NULL)
- {
- if (CompareX(old_x, server_x))
- {
- // Matched exactly to the certificate that is already registered
- if (old_x != NULL)
- {
- FreeX(old_x);
- }
- return true;
- }
- else
- {
- dlg.DiffWarning = true;
- }
- }
- // Because this certificate can not be trusted, confirm to be trusted by showing a dialog box
- UniStrCpy(dlg.AccountName, sizeof(dlg.AccountName), a->ClientOption->AccountName);
- StrCpy(dlg.ServerName, sizeof(dlg.ServerName), a->ClientOption->Hostname);
- dlg.x = server_x;
- dlg.old_x = old_x;
-
- dlg.Session = s;
- AddRef(s->ref);
- CncCheckCert(s, &dlg);
- ReleaseSession(s);
- if (old_x != NULL)
- {
- FreeX(old_x);
- }
- if (dlg.Ok && dlg.SaveServerCert)
- {
- // Save the server certificate and trust it from the next time
- Lock(a->lock);
- {
- if (a->ServerCert != NULL)
- {
- FreeX(a->ServerCert);
- }
- a->ServerCert = CloneX(server_x);
- }
- Unlock(a->lock);
- CiSaveConfigurationFile(s->Cedar->Client);
- }
- return dlg.Ok;
- #else // OS_WIN32
- ACCOUNT *a;
- X *old_x = NULL;
- // Validate arguments
- if (s == NULL || c == NULL || server_x == NULL)
- {
- return false;
- }
- if (expired != NULL)
- {
- *expired = false;
- }
- a = s->Account;
- if (a == NULL)
- {
- return false;
- }
- Lock(a->lock);
- {
- if (a->CheckServerCert == false)
- {
- // Not to validate the server certificate
- Unlock(a->lock);
- return true;
- }
- if (a->ServerCert != NULL)
- {
- old_x = CloneX(a->ServerCert);
- }
- }
- Unlock(a->lock);
- if (CheckXDateNow(server_x) == false)
- {
- // Expired
- if (old_x != NULL)
- {
- FreeX(old_x);
- }
- if (expired != NULL)
- {
- *expired = true;
- }
- return false;
- }
- if (old_x != NULL)
- {
- if (CompareX(old_x, server_x))
- {
- // Exactly matched to the certificate that is already registered
- if (old_x != NULL)
- {
- FreeX(old_x);
- }
- return true;
- }
- else
- {
- // Mismatch
- if (old_x != NULL)
- {
- FreeX(old_x);
- }
- return false;
- }
- }
- if (old_x != NULL)
- {
- FreeX(old_x);
- }
- return false;
- #endif // OS_WIN32
- }
- // Signature procedure with a secure device
- bool CiSecureSignProc(SESSION *s, CONNECTION *c, SECURE_SIGN *sign)
- {
- // The UI is available in Win32
- return CncSecureSignDlg(sign);
- }
- #ifdef OS_WIN32
- // Signing procedure (for Win32)
- bool Win32CiSecureSign(SECURE_SIGN *sign)
- {
- bool ret = false;
- BUF *random;
- // Validate arguments
- if (sign == NULL)
- {
- return false;
- }
- random = NewBuf();
- WriteBuf(random, sign->Random, SHA1_SIZE);
- // Batch processing
- {
- WINUI_SECURE_BATCH batch[] =
- {
- {WINUI_SECURE_READ_CERT, sign->SecurePublicCertName, true, NULL, NULL, NULL, NULL, NULL, NULL},
- {WINUI_SECURE_SIGN_WITH_KEY, sign->SecurePrivateKeyName, true, random, NULL, NULL, NULL, NULL, NULL}
- };
- if (SecureDeviceWindow(NULL, batch, sizeof(batch) / sizeof(batch[0]),
- sign->UseSecureDeviceId, sign->BitmapId) == false)
- {
- // Failure
- if (batch[0].OutputX != 0)
- {
- FreeX(batch[0].OutputX);
- }
- ret = false;
- }
- else
- {
- // Success
- ret = true;
- sign->ClientCert = batch[0].OutputX;
- Copy(sign->Signature, batch[1].OutputSign, 128);
- }
- }
- FreeBuf(random);
- return ret;
- }
- #endif // OS_WIN32
- // Disconnect
- bool CtDisconnect(CLIENT *c, RPC_CLIENT_CONNECT *connect, bool inner)
- {
- bool ret = false;
- ACCOUNT t, *r;
- SESSION *s = NULL;
- // Validate arguments
- if (c == NULL || connect == NULL)
- {
- return false;
- }
- LockList(c->AccountList);
- {
- // Search for account
- t.ClientOption = ZeroMalloc(sizeof(CLIENT_OPTION));
- UniStrCpy(t.ClientOption->AccountName, sizeof(t.ClientOption->AccountName), connect->AccountName);
- r = Search(c->AccountList, &t);
- if (r == NULL)
- {
- // Specified account isn't found
- UnlockList(c->AccountList);
- Free(t.ClientOption);
- CiSetError(c, ERR_ACCOUNT_NOT_FOUND);
- return false;
- }
- Free(t.ClientOption);
- Lock(r->lock);
- {
- if (r->ClientSession == NULL)
- {
- // Not connected
- CiSetError(c, ERR_ACCOUNT_INACTIVE);
- }
- else
- {
- s = r->ClientSession;
- AddRef(s->ref);
- // Disconnect complete
- r->ClientSession = NULL;
- ret = true;
- }
- }
- Unlock(r->lock);
- }
- UnlockList(c->AccountList);
- if (s != NULL)
- {
- // Disconnect the connection (Wait until the disconnection is complete)
- CLog(c, "LC_DISCONNECT", connect->AccountName);
- StopSession(s);
- ReleaseSession(s);
- }
- if (ret != false)
- {
- CiNotify(c);
- }
- return ret;
- }
- // Connect
- bool CtConnect(CLIENT *c, RPC_CLIENT_CONNECT *connect)
- {
- bool ret = false;
- RPC_CLIENT_ENUM_VLAN t;
- // Validate arguments
- if (c == NULL || connect == NULL)
- {
- return false;
- }
- Lock(c->lockForConnect);
- {
- Zero(&t, sizeof(t));
- if (CtEnumVLan(c, &t))
- {
- if (t.NumItem == 0)
- {
- // There are no virtual LAN cards in the system
- if (OS_IS_WINDOWS_NT(GetOsInfo()->OsType) || OS_IS_UNIX(GetOsInfo()->OsType))
- {
- // Only in Linux system or Windows NT system,
- // create a new virtual LAN card which named as "VPN" automatically
- RPC_CLIENT_CREATE_VLAN t;
- Zero(&t, sizeof(t));
- StrCpy(t.DeviceName, sizeof(t.DeviceName), "VPN");
- CtCreateVLan(c, &t);
- }
- }
- CiFreeClientEnumVLan(&t);
- }
- }
- Unlock(c->lockForConnect);
- CiNormalizeAccountVLan(c);
- // Ensure successfully VPN communication by changing the irrational WCM settings in the case of Windows 8 or later
- CiDisableWcmNetworkMinimize(c);
- LockList(c->AccountList);
- {
- ACCOUNT t, *r;
- bool unix_disabled = false;
- // Search for account
- t.ClientOption = ZeroMalloc(sizeof(CLIENT_OPTION));
- UniStrCpy(t.ClientOption->AccountName, sizeof(t.ClientOption->AccountName), connect->AccountName);
- r = Search(c->AccountList, &t);
- if (r == NULL)
- {
- // Specified account isn't found
- UnlockList(c->AccountList);
- Free(t.ClientOption);
- CiSetError(c, ERR_ACCOUNT_NOT_FOUND);
- return false;
- }
- Free(t.ClientOption);
- #ifndef OS_WIN32
- // Search for the virtual LAN card
- LockList(c->UnixVLanList);
- {
- UNIX_VLAN *v, t;
- Zero(&t, sizeof(t));
- StrCpy(t.Name, sizeof(t.Name), r->ClientOption->DeviceName);
- v = Search(c->UnixVLanList, &t);
- if (v == NULL)
- {
- UnlockList(c->UnixVLanList);
- CiSetError(c, ERR_OBJECT_NOT_FOUND);
- return false;
- }
- unix_disabled = v->Enabled ? false : true;
- }
- UnlockList(c->UnixVLanList);
- #endif // OS_WIN32
- Lock(r->lock);
- {
- bool already_used = false;
- UINT i;
- if (r->ClientSession != NULL)
- {
- // Already in connecting
- CiSetError(c, ERR_ACCOUNT_ACTIVE);
- }
- else if (r->ClientAuth->AuthType == CLIENT_AUTHTYPE_SECURE &&
- client->UseSecureDeviceId == 0)
- {
- // Secure device is not specified
- CiSetError(c, ERR_NO_SECURE_DEVICE_SPECIFIED);
- }
- #ifdef OS_WIN32
- else if (MsIsVLanExists(VLAN_ADAPTER_NAME_TAG, r->ClientOption->DeviceName) == false &&
- MsIsVLanExists(VLAN_ADAPTER_NAME_TAG_OLD, r->ClientOption->DeviceName) == false)
- {
- // Virtual LAN card can not be found
- CiSetError(c, ERR_VLAN_FOR_ACCOUNT_NOT_FOUND);
- CiNotify(c);
- CiSendGlobalPulse(c);
- }
- else if (MsIsVLanEnabled(r->ClientOption->DeviceName) == false)
- {
- // The virtual LAN card is disabled
- CiSetError(c, ERR_VLAN_FOR_ACCOUNT_DISABLED);
- CiNotify(c);
- CiSendGlobalPulse(c);
- }
- #else // OS_WIN32
- else if (unix_disabled)
- {
- // The virtual LAN card is disabled
- CiSetError(c, ERR_VLAN_FOR_ACCOUNT_DISABLED);
- CiNotify(c);
- CiSendGlobalPulse(c);
- }
- #endif // OS_WIN32
- else
- {
- // Check whether the virtual LAN card is being used by a different account already
- for (i = 0;i < LIST_NUM(c->AccountList);i++)
- {
- ACCOUNT *a = LIST_DATA(c->AccountList, i);
- if (a != r)
- {
- if (StrCmpi(a->ClientOption->DeviceName,
- r->ClientOption->DeviceName) == 0)
- {
- if (a->ClientSession != NULL)
- {
- already_used = true;
- break;
- }
- }
- }
- }
- if (already_used)
- {
- CiSetError(c, ERR_VLAN_FOR_ACCOUNT_USED);
- }
- else
- {
- // Start the connection
- PACKET_ADAPTER *pa = VLanGetPacketAdapter();
- if (r->ClientAuth->AuthType == CLIENT_AUTHTYPE_SECURE)
- {
- // Register a procedure for secure device authentication
- r->ClientAuth->SecureSignProc = CiSecureSignProc;
- }
- else
- {
- r->ClientAuth->SecureSignProc = NULL;
- }
- if (r->CheckServerCert)
- {
- // Register a procedure to validate the server certificate
- r->ClientAuth->CheckCertProc = CiCheckCertProc;
- }
- else
- {
- r->ClientAuth->CheckCertProc = NULL;
- }
- r->StatusPrinter = CiClientStatusPrinter;
- r->LastConnectDateTime = SystemTime64();
- CLog(c, "LC_CONNECT", connect->AccountName);
- r->ClientSession = NewClientSessionEx(c->Cedar, r->ClientOption, r->ClientAuth, pa, r);
- Notify(r->ClientSession, CLIENT_NOTIFY_ACCOUNT_CHANGED);
- ret = true;
- }
- }
- }
- Unlock(r->lock);
- }
- UnlockList(c->AccountList);
- CiSaveConfigurationFile(c);
- return ret;
- }
- // Get the account information
- bool CtGetAccount(CLIENT *c, RPC_CLIENT_GET_ACCOUNT *a)
- {
- // Validate arguments
- if (c == NULL || a == NULL)
- {
- return false;
- }
- LockList(c->AccountList);
- {
- ACCOUNT t, *r;
- // Search for account
- t.ClientOption = ZeroMalloc(sizeof(CLIENT_OPTION));
- UniStrCpy(t.ClientOption->AccountName, sizeof(t.ClientOption->AccountName), a->AccountName);
- r = Search(c->AccountList, &t);
- if (r == NULL)
- {
- // Specified account can not be found
- UnlockList(c->AccountList);
- Free(t.ClientOption);
- CiSetError(c, ERR_ACCOUNT_NOT_FOUND);
- return false;
- }
- Free(t.ClientOption);
- Lock(r->lock);
- {
- // Copy the client option
- if (a->ClientOption != NULL)
- {
- Free(a->ClientOption);
- }
- a->ClientOption = ZeroMalloc(sizeof(CLIENT_OPTION));
- Copy(a->ClientOption, r->ClientOption, sizeof(CLIENT_OPTION));
- // Copy the authentication data
- if (a->ClientAuth != NULL)
- {
- CiFreeClientAuth(a->ClientAuth);
- }
- a->ClientAuth = CopyClientAuth(r->ClientAuth);
- a->StartupAccount = r->StartupAccount;
- a->CheckServerCert = r->CheckServerCert;
- a->ServerCert = NULL;
- if (r->ServerCert != NULL)
- {
- a->ServerCert = CloneX(r->ServerCert);
- }
- // Shortcut Key
- Copy(a->ShortcutKey, r->ShortcutKey, SHA1_SIZE);
- a->CreateDateTime = r->CreateDateTime;
- a->LastConnectDateTime = r->LastConnectDateTime;
- a->UpdateDateTime = r->UpdateDateTime;
- }
- Unlock(r->lock);
- }
- UnlockList(c->AccountList);
- return true;
- }
- // Change the account name
- bool CtRenameAccount(CLIENT *c, RPC_RENAME_ACCOUNT *rename, bool inner)
- {
- bool ret;
- // Validate arguments
- if (c == NULL || rename == NULL)
- {
- return false;
- }
- ret = false;
- if (UniStrCmp(rename->NewName, rename->OldName) == 0)
- {
- // The name has not been changed
- return true;
- }
- LockList(c->AccountList);
- {
- ACCOUNT t, *r, *r2;
- if (UniStrLen(rename->NewName) == 0)
- {
- // Name is invalid
- CiSetError(c, ERR_INVALID_VALUE);
- UnlockList(c->AccountList);
- return false;
- }
- // Search for old account name
- t.ClientOption = ZeroMalloc(sizeof(CLIENT_OPTION));
- UniStrCpy(t.ClientOption->AccountName, sizeof(t.ClientOption->AccountName), rename->OldName);
- r = Search(c->AccountList, &t);
- if (r == NULL)
- {
- // Specified account can not be found
- UnlockList(c->AccountList);
- Free(t.ClientOption);
- CiSetError(c, ERR_ACCOUNT_NOT_FOUND);
- return false;
- }
- Free(t.ClientOption);
- // Search for a new account name
- t.ClientOption = ZeroMalloc(sizeof(CLIENT_OPTION));
- UniStrCpy(t.ClientOption->AccountName, sizeof(t.ClientOption->AccountName), rename->NewName);
- r2 = Search(c->AccountList, &t);
- if (r2 != NULL)
- {
- // Account with the specified name already exists
- UnlockList(c->AccountList);
- Free(t.ClientOption);
- CiSetError(c, ERR_ACCOUNT_ALREADY_EXISTS);
- return false;
- }
- Free(t.ClientOption);
- Lock(r->lock);
- {
- // Check the operating state of the account
- if (r->ClientSession != NULL)
- {
- // The Account is working
- Unlock(r->lock);
- UnlockList(c->AccountList);
- CiSetError(c, ERR_ACCOUNT_ACTIVE);
- return false;
- }
- // Update the account name
- UniStrCpy(r->ClientOption->AccountName, sizeof(r->ClientOption->AccountName),
- rename->NewName);
- CLog(c, "LC_RENAME_ACCOUNT", rename->OldName, rename->NewName);
- ret = true;
- }
- Unlock(r->lock);
- Sort(c->AccountList);
- }
- UnlockList(c->AccountList);
- CiSaveConfigurationFile(c);
- CiNotify(c);
- return ret;
- }
- // Set the client configuration
- bool CtSetClientConfig(CLIENT *c, CLIENT_CONFIG *o)
- {
- KEEP *k;
- // Validate arguments
- if (c == NULL || o == NULL)
- {
- return false;
- }
- if (o->UseKeepConnect)
- {
- if (IsEmptyStr(o->KeepConnectHost) ||
- o->KeepConnectPort == 0 ||
- o->KeepConnectPort >= 65536)
- {
- CiSetError(c, ERR_INVALID_PARAMETER);
- return false;
- }
- }
- Lock(c->lock);
- {
- Copy(&c->Config, o, sizeof(CLIENT_CONFIG));
- }
- Unlock(c->lock);
- // Save the settings
- CiSaveConfigurationFile(c);
- // Apply the Keep Connect
- k = c->Keep;
- Lock(k->lock);
- {
- if (o->UseKeepConnect)
- {
- StrCpy(k->ServerName, sizeof(k->ServerName), c->Config.KeepConnectHost);
- k->ServerPort = c->Config.KeepConnectPort;
- k->Interval = c->Config.KeepConnectInterval * 1000;
- k->UdpMode = (c->Config.KeepConnectProtocol == CONNECTION_UDP) ? true : false;
- k->Enable = true;
- }
- else
- {
- k->Enable = false;
- }
- }
- Unlock(k->lock);
- return true;
- }
- // Get the network client configuration
- bool CtGetClientConfig(CLIENT *c, CLIENT_CONFIG *o)
- {
- // Validate arguments
- if (c == NULL || o == NULL)
- {
- return false;
- }
- Lock(c->lock);
- {
- Copy(o, &c->Config, sizeof(CLIENT_CONFIG));
- }
- Unlock(c->lock);
- return true;
- }
- // Unset the startup attribute of the account
- bool CtRemoveStartupAccount(CLIENT *c, RPC_CLIENT_DELETE_ACCOUNT *a)
- {
- bool ret;
- // Validate arguments
- if (c == NULL || a == NULL)
- {
- return false;
- }
- ret = false;
- LockList(c->AccountList);
- {
- ACCOUNT t, *r;
- // Search for an Account
- t.ClientOption = ZeroMalloc(sizeof(CLIENT_OPTION));
- UniStrCpy(t.ClientOption->AccountName, sizeof(t.ClientOption->AccountName), a->AccountName);
- r = Search(c->AccountList, &t);
- if (r == NULL)
- {
- // Specified account can not be found
- UnlockList(c->AccountList);
- Free(t.ClientOption);
- CiSetError(c, ERR_ACCOUNT_NOT_FOUND);
- return false;
- }
- Free(t.ClientOption);
- Lock(r->lock);
- {
- // Unset the startup account
- ret = true;
- r->StartupAccount = false;
- }
- Unlock(r->lock);
- }
- UnlockList(c->AccountList);
- if (ret)
- {
- CiSaveConfigurationFile(c);
- CiNotify(c);
- }
- return ret;
- }
- // Set the account as a start-up account
- bool CtSetStartupAccount(CLIENT *c, RPC_CLIENT_DELETE_ACCOUNT *a, bool inner)
- {
- bool ret;
- // Validate arguments
- if (c == NULL || a == NULL)
- {
- return false;
- }
- ret = false;
- LockList(c->AccountList);
- {
- ACCOUNT t, *r;
- // Search for an account
- t.ClientOption = ZeroMalloc(sizeof(CLIENT_OPTION));
- UniStrCpy(t.ClientOption->AccountName, sizeof(t.ClientOption->AccountName), a->AccountName);
- r = Search(c->AccountList, &t);
- if (r == NULL)
- {
- // Specified account can not be found
- UnlockList(c->AccountList);
- Free(t.ClientOption);
- CiSetError(c, ERR_ACCOUNT_NOT_FOUND);
- return false;
- }
- Free(t.ClientOption);
- Lock(r->lock);
- {
- // Set to a start-up account
- ret = true;
- r->StartupAccount = true;
- }
- Unlock(r->lock);
- }
- UnlockList(c->AccountList);
- if (ret)
- {
- CiSaveConfigurationFile(c);
- CiNotify(c);
- }
- return ret;
- }
- // Delete the account
- bool CtDeleteAccount(CLIENT *c, RPC_CLIENT_DELETE_ACCOUNT *a, bool inner)
- {
- bool ret;
- // Validate arguments
- if (c == NULL || a == NULL)
- {
- return false;
- }
- ret = false;
- if (c->Halt)
- {
- // Don't allow the removal of the account in the process of stopping
- CiSetError(c, ERR_INTERNAL_ERROR);
- return false;
- }
- LockList(c->AccountList);
- {
- ACCOUNT t, *r;
- // Search for an Account
- t.ClientOption = ZeroMalloc(sizeof(CLIENT_OPTION));
- UniStrCpy(t.ClientOption->AccountName, sizeof(t.ClientOption->AccountName), a->AccountName);
- r = Search(c->AccountList, &t);
- if (r == NULL)
- {
- // Specified account can not be found
- UnlockList(c->AccountList);
- Free(t.ClientOption);
- CiSetError(c, ERR_ACCOUNT_NOT_FOUND);
- return false;
- }
- Free(t.ClientOption);
- Lock(r->lock);
- {
- // Check the operating state of the account
- if (r->ClientSession != NULL)
- {
- // The account is active
- Unlock(r->lock);
- UnlockList(c->AccountList);
- CiSetError(c, ERR_ACCOUNT_ACTIVE);
- return false;
- }
- // Remove this account from the list
- Delete(c->AccountList, r);
- }
- Unlock(r->lock);
- // Free the memory of this account
- CiFreeAccount(r);
- CLog(c, "LC_DELETE_ACCOUNT", a->AccountName);
- ret = true;
- }
- UnlockList(c->AccountList);
- if (ret)
- {
- CiSaveConfigurationFile(c);
- CiNotify(c);
- }
- return ret;
- }
- // Enumeration of accounts
- bool CtEnumAccount(CLIENT *c, RPC_CLIENT_ENUM_ACCOUNT *e)
- {
- // Validate arguments
- if (c == NULL || e == NULL)
- {
- return false;
- }
- LockList(c->AccountList);
- {
- UINT i;
- // Number of accounts
- e->NumItem = LIST_NUM(c->AccountList);
- e->Items = ZeroMalloc(sizeof(RPC_CLIENT_ENUM_ACCOUNT_ITEM *) * e->NumItem);
- for (i = 0;i < e->NumItem;i++)
- {
- ACCOUNT *a = LIST_DATA(c->AccountList, i);
- RPC_CLIENT_ENUM_ACCOUNT_ITEM *item = ZeroMalloc(sizeof(RPC_CLIENT_ENUM_ACCOUNT_ITEM));
- e->Items[i] = item;
- // Account name
- UniStrCpy(item->AccountName, sizeof(item->AccountName), a->ClientOption->AccountName);
- // User name
- StrCpy(item->UserName, sizeof(item->UserName), a->ClientAuth->Username);
- // Server name
- StrCpy(item->ServerName, sizeof(item->ServerName), a->ClientOption->Hostname);
- // Proxy type
- item->ProxyType = a->ClientOption->ProxyType;
- // Device name
- StrCpy(item->DeviceName, sizeof(item->DeviceName), a->ClientOption->DeviceName);
- // Proxy information
- if (item->ProxyType != PROXY_DIRECT)
- {
- StrCpy(item->ProxyName, sizeof(item->ProxyName), a->ClientOption->ProxyName);
- }
- // Startup
- item->StartupAccount = a->StartupAccount;
- // Active flag
- item->Active = (a->ClientSession == NULL ? false : true);
- // Connection flag
- item->Connected = (item->Active == false) ? false : a->ClientSession->ConnectSucceed;
- // Port number
- item->Port = a->ClientOption->Port;
- // Virtual HUB name
- StrCpy(item->HubName, sizeof(item->HubName), a->ClientOption->HubName);
- item->CreateDateTime = a->CreateDateTime;
- item->LastConnectDateTime = a->LastConnectDateTime;
- item->UpdateDateTime = a->UpdateDateTime;
- }
- }
- UnlockList(c->AccountList);
- return true;
- }
- // Configure the account
- bool CtSetAccount(CLIENT *c, RPC_CLIENT_CREATE_ACCOUNT *a, bool inner)
- {
- // Validate arguments
- if (c == NULL || a == NULL)
- {
- return false;
- }
- // Check whether an account already exists
- LockList(c->AccountList);
- {
- ACCOUNT t, *ret;
- t.ClientOption = ZeroMalloc(sizeof(CLIENT_OPTION));
- UniStrCpy(t.ClientOption->AccountName, sizeof(t.ClientOption->AccountName),
- a->ClientOption->AccountName);
- ret = Search(c->AccountList, &t);
- if (ret == NULL)
- {
- // Not exist
- UnlockList(c->AccountList);
- Free(t.ClientOption);
- CiSetError(c, ERR_ACCOUNT_NOT_FOUND);
- return false;
- }
- Free(t.ClientOption);
- if (a->ClientAuth->AuthType == CLIENT_AUTHTYPE_CERT)
- {
- if (a->ClientAuth->ClientX == NULL ||
- a->ClientAuth->ClientX->is_compatible_bit == false ||
- a->ClientAuth->ClientK == NULL)
- {
- // Client certificate is invalid
- UnlockList(c->AccountList);
- CiSetError(c, ERR_NOT_RSA_1024);
- return false;
- }
- }
- if (a->ServerCert != NULL && a->ServerCert->is_compatible_bit == false)
- {
- // Server certificate is invalid
- UnlockList(c->AccountList);
- CiSetError(c, ERR_NOT_RSA_1024);
- return false;
- }
- Lock(ret->lock);
- {
- #if 0
- // Rewriting of the configuration is done even account running in the current version
- // (New setting isn't applied until connecting next time)
- if (ret->ClientSession != NULL)
- {
- // The account is operating
- Unlock(ret->lock);
- UnlockList(c->AccountList);
- CiSetError(c, ERR_ACCOUNT_ACTIVE);
- return false;
- }
- #endif
- // Delete the client authentication data
- CiFreeClientAuth(ret->ClientAuth);
- // Copy the client authentication data
- ret->ClientAuth = CopyClientAuth(a->ClientAuth);
- // Delete the client option
- Free(ret->ClientOption);
- // Copy the client option
- ret->ClientOption = ZeroMalloc(sizeof(CLIENT_OPTION));
- Copy(ret->ClientOption, a->ClientOption, sizeof(CLIENT_OPTION));
- ret->StartupAccount = a->StartupAccount;
- ret->CheckServerCert = a->CheckServerCert;
- if (a->ServerCert != NULL)
- {
- if (ret->ServerCert != NULL)
- {
- FreeX(ret->ServerCert);
- }
- ret->ServerCert = CloneX(a->ServerCert);
- }
- else
- {
- if (ret->ServerCert != NULL)
- {
- FreeX(ret->ServerCert);
- }
- ret->ServerCert = false;
- }
- ret->UpdateDateTime = SystemTime64();
- }
- Unlock(ret->lock);
- }
- UnlockList(c->AccountList);
- CiSaveConfigurationFile(c);
- CiNotify(c);
- return true;
- }
- // Create an account
- bool CtCreateAccount(CLIENT *c, RPC_CLIENT_CREATE_ACCOUNT *a, bool inner)
- {
- // Validate arguments
- if (c == NULL || a == NULL)
- {
- return false;
- }
- // Check whether an account already exists
- LockList(c->AccountList);
- {
- ACCOUNT t, *ret, *new_account;
- t.ClientOption = ZeroMalloc(sizeof(CLIENT_OPTION));
- UniStrCpy(t.ClientOption->AccountName, sizeof(t.ClientOption->AccountName),
- a->ClientOption->AccountName);
- ret = Search(c->AccountList, &t);
- if (ret != NULL)
- {
- // Already exist
- UnlockList(c->AccountList);
- Free(t.ClientOption);
- CiSetError(c, ERR_ACCOUNT_ALREADY_EXISTS);
- return false;
- }
- Free(t.ClientOption);
- if (UniStrLen(a->ClientOption->AccountName) == 0)
- {
- // The name is invalid
- UnlockList(c->AccountList);
- CiSetError(c, ERR_INVALID_VALUE);
- return false;
- }
- if (a->ClientAuth->AuthType == CLIENT_AUTHTYPE_CERT)
- {
- if (a->ClientAuth->ClientX == NULL ||
- a->ClientAuth->ClientX->is_compatible_bit == false ||
- a->ClientAuth->ClientK == NULL)
- {
- // The client certificate is invalid
- UnlockList(c->AccountList);
- CiSetError(c, ERR_NOT_RSA_1024);
- return false;
- }
- }
- if (a->ServerCert != NULL && a->ServerCert->is_compatible_bit == false)
- {
- // The server certificate is invalid
- UnlockList(c->AccountList);
- CiSetError(c, ERR_NOT_RSA_1024);
- return false;
- }
- // Add a new account
- new_account = ZeroMalloc(sizeof(ACCOUNT));
- new_account->lock = NewLock();
- // Copy the client authentication data
- new_account->ClientAuth = CopyClientAuth(a->ClientAuth);
- // Copy the client option
- new_account->ClientOption = ZeroMalloc(sizeof(CLIENT_OPTION));
- Copy(new_account->ClientOption, a->ClientOption, sizeof(CLIENT_OPTION));
- new_account->StartupAccount = a->StartupAccount;
- new_account->CheckServerCert = a->CheckServerCert;
- if (a->ServerCert != NULL)
- {
- new_account->ServerCert = CloneX(a->ServerCert);
- }
- // Shortcut Key
- if (IsZero(a->ShortcutKey, SHA1_SIZE))
- {
- Rand(new_account->ShortcutKey, SHA1_SIZE);
- }
- else
- {
- Copy(new_account->ShortcutKey, a->ShortcutKey, SHA1_SIZE);
- }
- new_account->CreateDateTime = new_account->UpdateDateTime = SystemTime64();
- // Insert into the list
- Insert(c->AccountList, new_account);
- CLog(c, "LC_NEW_ACCOUNT", a->ClientOption->AccountName);
- }
- UnlockList(c->AccountList);
- CiNormalizeAccountVLan(c);
- CiSaveConfigurationFile(c);
- CiNotify(c);
- return true;
- }
- // Release the account acquisition structure
- void CiFreeClientGetAccount(RPC_CLIENT_GET_ACCOUNT *a)
- {
- // Validate arguments
- if (a == NULL)
- {
- return;
- }
- // Release the account information
- if (a->ServerCert != NULL)
- {
- FreeX(a->ServerCert);
- }
- CiFreeClientAuth(a->ClientAuth);
- Free(a->ClientOption);
- }
- // Release the account creation structure
- void CiFreeClientCreateAccount(RPC_CLIENT_CREATE_ACCOUNT *a)
- {
- // Validate arguments
- if (a == NULL)
- {
- return;
- }
- // Release the account information
- if (a->ServerCert != NULL)
- {
- FreeX(a->ServerCert);
- }
- CiFreeClientAuth(a->ClientAuth);
- Free(a->ClientOption);
- }
- // Stop the virtual LAN card
- bool CtDisableVLan(CLIENT *c, RPC_CLIENT_CREATE_VLAN *vlan)
- {
- UINT i;
- bool used;
- // Validate arguments
- if (c == NULL || vlan == NULL)
- {
- return false;
- }
- #ifndef OS_WIN32
- #ifdef NO_VLAN
- if (GetOsInfo()->OsType == OSTYPE_MACOS_X)
- {
- // Can not be added or removed the virtual LAN card in MacOS X
- CiSetError(c, ERR_NOT_SUPPORTED);
- return false;
- }
- #endif // NO_VLAN
- // Check whether the virtual LAN card with the specified name is not
- // being used by one or more accounts
- used = false;
- LockList(c->AccountList);
- {
- for (i = 0;i < LIST_NUM(c->AccountList);i++)
- {
- ACCOUNT *a = LIST_DATA(c->AccountList, i);
- if (StrCmpi(a->ClientOption->DeviceName, vlan->DeviceName) == 0)
- {
- Lock(a->lock);
- {
- if (a->ClientSession != NULL)
- {
- used = true;
- }
- }
- Unlock(a->lock);
- }
- }
- }
- UnlockList(c->AccountList);
- // Search for the virtual LAN card
- LockList(c->UnixVLanList);
- {
- UNIX_VLAN *v, t;
- Zero(&t, sizeof(t));
- StrCpy(t.Name, sizeof(t.Name), vlan->DeviceName);
- v = Search(c->UnixVLanList, &t);
- if (v == NULL)
- {
- UnlockList(c->UnixVLanList);
- CiSetError(c, ERR_OBJECT_NOT_FOUND);
- return false;
- }
- // Stop
- v->Enabled = false;
- }
- UnlockList(c->UnixVLanList);
- CiSaveConfigurationFile(c);
- CiNotify(c);
- CiSendGlobalPulse(c);
- return true;
- #else // OS_WIN32
- // Check whether the virtual LAN card with the specified name is not
- // being used by one or more accounts
- used = false;
- LockList(c->AccountList);
- {
- for (i = 0;i < LIST_NUM(c->AccountList);i++)
- {
- ACCOUNT *a = LIST_DATA(c->AccountList, i);
- if (StrCmpi(a->ClientOption->DeviceName, vlan->DeviceName) == 0)
- {
- Lock(a->lock);
- {
- if (a->ClientSession != NULL)
- {
- used = true;
- }
- }
- Unlock(a->lock);
- }
- }
- }
- UnlockList(c->AccountList);
- #if 0
- if (used)
- {
- // In using
- CiSetError(c, ERR_VLAN_IS_USED);
- return false;
- }
- #endif
- // Check whether the virtual LAN card are present
- if (MsIsVLanExists(VLAN_ADAPTER_NAME_TAG, vlan->DeviceName) == false &&
- MsIsVLanExists(VLAN_ADAPTER_NAME_TAG_OLD, vlan->DeviceName) == false)
- {
- CiSetError(c, ERR_OBJECT_NOT_FOUND);
- CiNotify(c);
- CiSendGlobalPulse(c);
- return false;
- }
- if (MsIs64BitWindows() && Is32() && MsIsAdmin())
- {
- // Execute the driver_installer to process since this Windows is 64 bit
- // but this code is 32 bit
- char tmp[MAX_SIZE];
- Format(tmp, sizeof(tmp), "disablevlan %s", vlan->DeviceName);
- if (MsExecDriverInstaller(tmp) == false)
- {
- CiSetError(c, ERR_VLAN_INSTALL_ERROR);
- CiNotify(c);
- CiSendGlobalPulse(c);
- return false;
- }
- }
- else
- {
- // Stop the virtual LAN card
- if (MsDisableVLan(vlan->DeviceName) == false)
- {
- CiSetError(c, ERR_VLAN_INSTALL_ERROR);
- CiNotify(c);
- CiSendGlobalPulse(c);
- return false;
- }
- }
- CiNotify(c);
- CiSendGlobalPulse(c);
- return true;
- #endif // OS_WIN32
- }
- // Start the virtual LAN card
- bool CtEnableVLan(CLIENT *c, RPC_CLIENT_CREATE_VLAN *vlan)
- {
- // Validate arguments
- if (c == NULL || vlan == NULL)
- {
- return false;
- }
- #ifndef OS_WIN32
- #ifdef NO_VLAN
- if (GetOsInfo()->OsType == OSTYPE_MACOS_X)
- {
- // Can not be added or removed the virtual LAN card in MacOS X
- CiSetError(c, ERR_NOT_SUPPORTED);
- return false;
- }
- #endif // NO_VLAN
- // Search the virtual LAN card
- LockList(c->UnixVLanList);
- {
- UNIX_VLAN *v, t;
- Zero(&t, sizeof(t));
- StrCpy(t.Name, sizeof(t.Name), vlan->DeviceName);
- v = Search(c->UnixVLanList, &t);
- if (v == NULL)
- {
- UnlockList(c->UnixVLanList);
- CiSetError(c, ERR_OBJECT_NOT_FOUND);
- return false;
- }
- // Enable
- v->Enabled = true;
- }
- UnlockList(c->UnixVLanList);
- CiSaveConfigurationFile(c);
- CiNotify(c);
- CiSendGlobalPulse(c);
- return true;
- #else // OS_WIN32
- // Check whether the virtual LAN card are present
- if (MsIsVLanExists(VLAN_ADAPTER_NAME_TAG, vlan->DeviceName) == false &&
- MsIsVLanExists(VLAN_ADAPTER_NAME_TAG_OLD, vlan->DeviceName) == false)
- {
- CiSetError(c, ERR_OBJECT_NOT_FOUND);
- CiNotify(c);
- CiSendGlobalPulse(c);
- return false;
- }
- if (MsIs64BitWindows() && Is32() && MsIsAdmin())
- {
- // Execute the driver_installer to process since this Windows is 64 bit
- // but this code is 32 bit
- char tmp[MAX_SIZE];
- Format(tmp, sizeof(tmp), "enablevlan %s", vlan->DeviceName);
- if (MsExecDriverInstaller(tmp) == false)
- {
- CiSetError(c, ERR_VLAN_INSTALL_ERROR);
- CiNotify(c);
- CiSendGlobalPulse(c);
- return false;
- }
- }
- else
- {
- // Start the virtual LAN card
- if (MsEnableVLan(vlan->DeviceName) == false)
- {
- CiSetError(c, ERR_VLAN_INSTALL_ERROR);
- CiNotify(c);
- CiSendGlobalPulse(c);
- return false;
- }
- }
- CiNotify(c);
- CiSendGlobalPulse(c);
- return true;
- #endif // OS_WIN32
- }
- // Delete the virtual LAN card
- bool CtDeleteVLan(CLIENT *c, RPC_CLIENT_CREATE_VLAN *d)
- {
- UINT i;
- bool used;
- // Validate arguments
- if (c == NULL || d == NULL)
- {
- return false;
- }
- #ifndef OS_WIN32
- #ifdef NO_VLAN
- if (GetOsInfo()->OsType == OSTYPE_MACOS_X)
- {
- // Can not be added or removed the virtual LAN card in MacOS X
- CiSetError(c, ERR_NOT_SUPPORTED);
- return false;
- }
- #endif // NO_VLAN
- // Check whether the virtual LAN card with the specified name is not
- // being used by one or more accounts
- used = false;
- LockList(c->AccountList);
- {
- for (i = 0;i < LIST_NUM(c->AccountList);i++)
- {
- ACCOUNT *a = LIST_DATA(c->AccountList, i);
- if (StrCmpi(a->ClientOption->DeviceName, d->DeviceName) == 0)
- {
- used = true;
- }
- }
- }
- UnlockList(c->AccountList);
- #if 0
- if (used)
- {
- // In using
- CiSetError(c, ERR_VLAN_IS_USED);
- return false;
- }
- #endif
- // Search for the virtual LAN card
- LockList(c->UnixVLanList);
- {
- UNIX_VLAN *v, t;
- Zero(&t, sizeof(t));
- StrCpy(t.Name, sizeof(t.Name), d->DeviceName);
- v = Search(c->UnixVLanList, &t);
- if (v == NULL)
- {
- UnlockList(c->UnixVLanList);
- CiSetError(c, ERR_OBJECT_NOT_FOUND);
- return false;
- }
- // Remove
- if (Delete(c->UnixVLanList, v))
- {
- Free(v);
- }
- CLog(c, "LC_DELETE_VLAN", d->DeviceName);
- UnixVLanDelete(d->DeviceName);
- }
- UnlockList(c->UnixVLanList);
- CiNormalizeAccountVLan(c);
- CiSaveConfigurationFile(c);
- CiNotify(c);
- CiSendGlobalPulse(c);
- return true;
- #else // OS_WIN32
- if (MsIsNt() == false)
- {
- // Not available in Win9x
- CiSetError(c, ERR_NOT_SUPPORTED);
- return false;
- }
- // Check whether the virtual LAN card are present
- if (MsIsVLanExists(VLAN_ADAPTER_NAME_TAG, d->DeviceName) == false &&
- MsIsVLanExists(VLAN_ADAPTER_NAME_TAG_OLD, d->DeviceName) == false)
- {
- CiSetError(c, ERR_OBJECT_NOT_FOUND);
- return false;
- }
- // Check whether the virtual LAN card with the specified name is not
- // being used by one or more accounts
- used = false;
- LockList(c->AccountList);
- {
- for (i = 0;i < LIST_NUM(c->AccountList);i++)
- {
- ACCOUNT *a = LIST_DATA(c->AccountList, i);
- if (StrCmpi(a->ClientOption->DeviceName, d->DeviceName) == 0)
- {
- used = true;
- }
- }
- }
- UnlockList(c->AccountList);
- #if 0
- if (used)
- {
- // In using
- CiSetError(c, ERR_VLAN_IS_USED);
- return false;
- }
- #endif
- if (MsIs64BitWindows() && Is32() && MsIsAdmin())
- {
- // Execute the driver_installer to process since this Windows is 64 bit
- // but this code is 32 bit
- char tmp[MAX_SIZE];
- Format(tmp, sizeof(tmp), "uninstvlan %s", d->DeviceName);
- if (MsExecDriverInstaller(tmp) == false)
- {
- CiSetError(c, ERR_VLAN_INSTALL_ERROR);
- return false;
- }
- }
- else
- {
- // Delete the virtual LAN card directly
- if (MsUninstallVLan(d->DeviceName) == false)
- {
- CiSetError(c, ERR_VLAN_INSTALL_ERROR);
- CiNotify(c);
- CiSendGlobalPulse(c);
- return false;
- }
- }
- CLog(c, "LC_DELETE_VLAN", d->DeviceName);
- CiNormalizeAccountVLan(c);
- CiNotify(c);
- CiSendGlobalPulse(c);
- return true;
- #endif // OS_WIN32
- }
- // Get the name of the first VLAN
- char *CiGetFirstVLan(CLIENT *c)
- {
- char *ret = NULL;
- RPC_CLIENT_ENUM_VLAN t;
- // Validate arguments
- if (c == NULL)
- {
- return NULL;
- }
- Zero(&t, sizeof(t));
- if (CtEnumVLan(c, &t) == false)
- {
- return NULL;
- }
- if (t.NumItem >= 1)
- {
- UINT i;
- char *tmp = t.Items[0]->DeviceName;
- for (i = 0;i < t.NumItem;i++)
- {
- if (t.Items[i]->Enabled)
- {
- tmp = t.Items[i]->DeviceName;
- }
- }
- ret = CopyStr(tmp);
- }
- CiFreeClientEnumVLan(&t);
- return ret;
- }
- // Enumerate virtual LAN cards
- bool CtEnumVLan(CLIENT *c, RPC_CLIENT_ENUM_VLAN *e)
- {
- UINT i;
- TOKEN_LIST *t;
- // Validate arguments
- if (c == NULL || e == NULL)
- {
- return false;
- }
- #ifndef OS_WIN32
- LockList(c->UnixVLanList);
- {
- e->NumItem = LIST_NUM(c->UnixVLanList);
- e->Items = ZeroMalloc(sizeof(RPC_CLIENT_ENUM_VLAN_ITEM *) * e->NumItem);
- for (i = 0;i < e->NumItem;i++)
- {
- RPC_CLIENT_ENUM_VLAN_ITEM *item;
- UNIX_VLAN *v;
- v = LIST_DATA(c->UnixVLanList, i);
- e->Items[i] = ZeroMalloc(sizeof(RPC_CLIENT_ENUM_VLAN_ITEM));
- item = e->Items[i];
- item->Enabled = v->Enabled;
- BinToStr(item->MacAddress, sizeof(item->MacAddress), v->MacAddress, 6);
- StrCpy(item->DeviceName, sizeof(item->DeviceName), v->Name);
- StrCpy(item->Version, sizeof(item->Version), c->Cedar->VerString);
- }
- }
- UnlockList(c->UnixVLanList);
- return true;
- #else // OS_WIN32
- // Enumeration
- t = MsEnumNetworkAdapters(VLAN_ADAPTER_NAME, VLAN_ADAPTER_NAME_OLD);
- if (t == NULL)
- {
- // Enumeration failure
- e->NumItem = 0;
- e->Items = ZeroMalloc(0);
- }
- else
- {
- // Enumeration success
- e->NumItem = t->NumTokens;
- e->Items = ZeroMalloc(sizeof(RPC_CLIENT_ENUM_VLAN_ITEM *) * e->NumItem);
- for (i = 0;i < e->NumItem;i++)
- {
- char *tmp;
- RPC_CLIENT_ENUM_VLAN_ITEM *item;
- e->Items[i] = ZeroMalloc(sizeof(RPC_CLIENT_ENUM_VLAN_ITEM));
- item = e->Items[i];
- StrCpy(item->DeviceName, sizeof(item->DeviceName), t->Token[i]);
- item->Enabled = MsIsVLanEnabled(item->DeviceName);
- tmp = MsGetMacAddress(VLAN_ADAPTER_NAME_TAG, item->DeviceName);
- if (tmp == NULL)
- {
- tmp = MsGetMacAddress(VLAN_ADAPTER_NAME_TAG_OLD, item->DeviceName);
- }
- StrCpy(item->MacAddress, sizeof(item->MacAddress), tmp);
- Free(tmp);
- tmp = MsGetDriverVersion(VLAN_ADAPTER_NAME_TAG, item->DeviceName);
- if (tmp == NULL)
- {
- tmp = MsGetDriverVersion(VLAN_ADAPTER_NAME_TAG_OLD, item->DeviceName);
- }
- StrCpy(item->Version, sizeof(item->Version), tmp);
- Free(tmp);
- }
- FreeToken(t);
- }
- return true;
- #endif // OS_WIN32
- }
- // Release the virtual LAN card enumeration
- void CiFreeClientEnumVLan(RPC_CLIENT_ENUM_VLAN *e)
- {
- UINT i;
- // Validate arguments
- if (e == NULL)
- {
- return;
- }
- for (i = 0;i < e->NumItem;i++)
- {
- Free(e->Items[i]);
- }
- Free(e->Items);
- }
- // Set the information about the virtual LAN card
- bool CtSetVLan(CLIENT *c, RPC_CLIENT_SET_VLAN *set)
- {
- // Validate arguments
- if (c == NULL || set == NULL)
- {
- return false;
- }
- #ifndef OS_WIN32
- LockList(c->UnixVLanList);
- {
- UNIX_VLAN t, *r;
- Zero(&t, sizeof(t));
- StrCpy(t.Name, sizeof(t.Name), set->DeviceName);
- r = Search(c->UnixVLanList, &t);
- if (r == NULL)
- {
- // Not exist
- CiSetError(c, ERR_VLAN_ALREADY_EXISTS);
- UnlockList(c->UnixVLanList);
- return false;
- }
- StrToMac(r->MacAddress, set->MacAddress);
- }
- UnlockList(c->UnixVLanList);
- CiSaveConfigurationFile(c);
- CiNotify(c);
- CiSendGlobalPulse(c);
- return true;
- #else // OS_WIN32
- // Check whether the virtual LAN card with the specified name already exists
- if (MsIsVLanExists(VLAN_ADAPTER_NAME_TAG, set->DeviceName) == false &&
- MsIsVLanExists(VLAN_ADAPTER_NAME_TAG_OLD, set->DeviceName) == false)
- {
- // Not exist
- CiSetError(c, ERR_OBJECT_NOT_FOUND);
- return false;
- }
- // Configuring MAC address
- MsSetMacAddress(VLAN_ADAPTER_NAME_TAG, set->DeviceName, set->MacAddress);
- MsSetMacAddress(VLAN_ADAPTER_NAME_TAG_OLD, set->DeviceName, set->MacAddress);
- CiNotify(c);
- CiSendGlobalPulse(c);
- return true;
- #endif // OS_WIN32
- }
- // Get the information about the virtual LAN card
- bool CtGetVLan(CLIENT *c, RPC_CLIENT_GET_VLAN *get)
- {
- char *tmp;
- // Validate arguments
- if (c == NULL || get == NULL)
- {
- return false;
- }
- #ifndef OS_WIN32
- // Unsupported
- CiSetError(c, ERR_NOT_SUPPORTED);
- return false;
- #else // OS_WIN32
- // Check whether the virtual LAN card with the specified name already exists
- if (MsIsVLanExists(VLAN_ADAPTER_NAME_TAG, get->DeviceName) == false &&
- MsIsVLanExists(VLAN_ADAPTER_NAME_TAG_OLD, get->DeviceName) == false)
- {
- // Not exist
- CiSetError(c, ERR_OBJECT_NOT_FOUND);
- return false;
- }
- // Activity
- get->Enabled = MsIsVLanEnabled(get->DeviceName);
- // MAC address
- tmp = MsGetMacAddress(VLAN_ADAPTER_NAME_TAG, get->DeviceName);
- if (tmp == NULL)
- {
- tmp = MsGetMacAddress(VLAN_ADAPTER_NAME_TAG_OLD, get->DeviceName);
- }
- StrCpy(get->MacAddress, sizeof(get->MacAddress), tmp);
- Free(tmp);
- // Version
- tmp = MsGetDriverVersion(VLAN_ADAPTER_NAME_TAG, get->DeviceName);
- if (tmp == NULL)
- {
- tmp = MsGetDriverVersion(VLAN_ADAPTER_NAME_TAG_OLD, get->DeviceName);
- }
- StrCpy(get->Version, sizeof(get->Version), tmp);
- Free(tmp);
- // File name
- tmp = MsGetDriverFileName(VLAN_ADAPTER_NAME_TAG, get->DeviceName);
- if (tmp == NULL)
- {
- tmp = MsGetDriverFileName(VLAN_ADAPTER_NAME_TAG_OLD, get->DeviceName);
- }
- StrCpy(get->FileName, sizeof(get->FileName), tmp);
- Free(tmp);
- // GUID
- tmp = MsGetNetworkAdapterGuid(VLAN_ADAPTER_NAME_TAG, get->DeviceName);
- if (tmp == NULL)
- {
- tmp = MsGetNetworkAdapterGuid(VLAN_ADAPTER_NAME_TAG_OLD, get->DeviceName);
- }
- StrCpy(get->Guid, sizeof(get->Guid), tmp);
- Free(tmp);
- return true;
- #endif // OS_WIN32
- }
- #ifdef OS_WIN32
- // Initialize the driver version information structure
- void CiInitDriverVerStruct(MS_DRIVER_VER *ver)
- {
- UINT cedar_ver = CEDAR_VER;
- // Validate arguments
- if (ver == NULL)
- {
- return;
- }
- Zero(ver, sizeof(MS_DRIVER_VER));
- ver->Year = BUILD_DATE_Y;
- ver->Month = BUILD_DATE_M;
- ver->Day = BUILD_DATE_D;
- ver->Major = cedar_ver / 100;
- ver->Minor = cedar_ver % 100;
- ver->Build = CEDAR_BUILD;
- }
- #endif // OS_WIN32
- // Upgrade the virtual LAN card
- bool CtUpgradeVLan(CLIENT *c, RPC_CLIENT_CREATE_VLAN *create)
- {
- bool use_old_name = false;
- #ifdef OS_WIN32
- KAKUSHI *k = NULL;
- MS_DRIVER_VER ver;
- #endif // OS_WIN32
- // Validate arguments
- if (c == NULL || create == NULL)
- {
- return false;
- }
- #ifndef OS_WIN32
- // Always succeed
- return true;
- #else // OS_WIN32
- CiInitDriverVerStruct(&ver);
- if (MsIsNt() == false)
- {
- // Not available in Win9x
- CiSetError(c, ERR_NOT_SUPPORTED);
- return false;
- }
- // Check whether the LAN card with the specified name already exists
- if (MsIsVLanExists(VLAN_ADAPTER_NAME_TAG, create->DeviceName) == false &&
- MsIsVLanExists(VLAN_ADAPTER_NAME_TAG_OLD, create->DeviceName) == false)
- {
- // Not exist
- CiSetError(c, ERR_OBJECT_NOT_FOUND);
- CiNotify(c);
- CiSendGlobalPulse(c);
- return false;
- }
- if (MsIsVLanExists(VLAN_ADAPTER_NAME_TAG_OLD, create->DeviceName))
- {
- use_old_name = true;
- }
- if (MsIsVista() == false)
- {
- k = InitKakushi();
- }
- if (MsIsVista() == false)
- {
- // Perform the installation (other than Windows Vista)
- if (MsUpgradeVLan(use_old_name ? VLAN_ADAPTER_NAME_TAG_OLD : VLAN_ADAPTER_NAME_TAG,
- use_old_name ? VLAN_CONNECTION_NAME_OLD : VLAN_CONNECTION_NAME,
- create->DeviceName, &ver) == false)
- {
- // Installation Failed
- FreeKakushi(k);
- CiSetError(c, ERR_VLAN_INSTALL_ERROR);
- CiNotify(c);
- CiSendGlobalPulse(c);
- return false;
- }
- }
- else
- {
- // Perform the installation (Windows Vista)
- char tmp[MAX_SIZE];
- Format(tmp, sizeof(tmp), "upgradevlan %s", create->DeviceName);
- if (CncExecDriverInstaller(tmp) == false)
- {
- // Installation Failed
- FreeKakushi(k);
- CiSetError(c, ERR_VLAN_INSTALL_ERROR);
- CiNotify(c);
- CiSendGlobalPulse(c);
- return false;
- }
- }
- FreeKakushi(k);
- CLog(c, "LC_UPDATE_VLAN", create->DeviceName);
- CiNotify(c);
- CiSendGlobalPulse(c);
- return true;
- #endif // OS_WIN32
- }
- // Create a virtual LAN card
- bool CtCreateVLan(CLIENT *c, RPC_CLIENT_CREATE_VLAN *create)
- {
- TOKEN_LIST *t;
- UINT max_len;
- #ifdef OS_WIN32
- KAKUSHI *k = NULL;
- #endif // OS_WIN32
- // Validate arguments
- if (c == NULL || create == NULL)
- {
- return false;
- }
- if (SearchStrEx(create->DeviceName, " ", 0, false) != INFINITE)
- {
- // Spaces in the name is not allowed
- CiSetError(c, ERR_INVALID_PARAMETER);
- return false;
- }
- #ifndef OS_WIN32
- // Non-Win32
- #ifdef NO_VLAN
- if (GetOsInfo()->OsType == OSTYPE_MACOS_X)
- {
- // A virtual LAN card can not be added or removed in MacOS X
- CiSetError(c, ERR_NOT_SUPPORTED);
- return false;
- }
- #endif // NO_VLAN
- // Check whether the specified name is valid or not
- if (IsSafeStr(create->DeviceName) == false)
- {
- // Name is invalid
- CiSetError(c, ERR_VLAN_INVALID_NAME);
- return false;
- }
- // Check whether the LAN card of the specified name already exists
- LockList(c->UnixVLanList);
- {
- UNIX_VLAN t, *r;
- Zero(&t, sizeof(t));
- StrCpy(t.Name, sizeof(t.Name), create->DeviceName);
- r = Search(c->UnixVLanList, &t);
- if (r != NULL)
- {
- // Already exist
- CiSetError(c, ERR_VLAN_ALREADY_EXISTS);
- UnlockList(c->UnixVLanList);
- return false;
- }
- // Register
- r = ZeroMalloc(sizeof(UNIX_VLAN));
- r->Enabled = true;
- GenMacAddress(r->MacAddress);
- StrCpy(r->Name, sizeof(r->Name), create->DeviceName);
- // Create a Tap
- if (UnixVLanCreate(r->Name, r->MacAddress) == false)
- {
- // Failure
- Free(r);
- CiSetError(c, ERR_VLAN_INSTALL_ERROR);
- UnlockList(c->UnixVLanList);
- return false;
- }
- CLog(c, "LC_CREATE_VLAN", create->DeviceName);
- Add(c->UnixVLanList, r);
- }
- UnlockList(c->UnixVLanList);
- CiNormalizeAccountVLan(c);
- CiNotify(c);
- CiSendGlobalPulse(c);
- CiSaveConfigurationFile(c);
- return true;
- #else // OS_WIN32
- if (OS_IS_WINDOWS_9X(GetOsInfo()->OsType))
- {
- // Only one LAN card is available in the Win9x
- TOKEN_LIST *t;
- t = MsEnumNetworkAdapters(VLAN_ADAPTER_NAME, VLAN_ADAPTER_NAME_OLD);
- if (t != NULL)
- {
- if (t->NumTokens >= 1)
- {
- FreeToken(t);
- CiSetError(c, ERR_NOT_SUPPORTED);
- return false;
- }
- FreeToken(t);
- }
- }
- // Check whether the specified name is valid or not
- if (IsSafeStr(create->DeviceName) == false)
- {
- // Name is invalid
- CiSetError(c, ERR_VLAN_INVALID_NAME);
- return false;
- }
- max_len = MsIsNt() ? MAX_DEVICE_NAME_LEN : MAX_DEVICE_NAME_LEN_9X;
- if (StrLen(create->DeviceName) > max_len)
- {
- // Name is too long
- CiSetError(c, ERR_VLAN_INVALID_NAME);
- return false;
- }
- // Regulation in Windows 8
- if (MsIsInfCatalogRequired())
- {
- if (CiIsValidVLanRegulatedName(create->DeviceName) == false)
- {
- // Name is invalid
- CiSetError(c, ERR_VLAN_INVALID_NAME);
- return false;
- }
- }
- // Check whether the LAN card with the specified name already exists
- if (MsIsVLanExists(VLAN_ADAPTER_NAME_TAG, create->DeviceName) ||
- MsIsVLanExists(VLAN_ADAPTER_NAME_TAG_OLD, create->DeviceName))
- {
- // Already exist
- CiSetError(c, ERR_VLAN_ALREADY_EXISTS);
- return false;
- }
- if (MsIsNt())
- {
- if (MsIsVista() == false)
- {
- k = InitKakushi();
- }
- }
- if (MsIsVista() == false)
- {
- MS_DRIVER_VER ver;
- CiInitDriverVerStruct(&ver);
- // Perform the installation (other than Windows Vista)
- if (MsInstallVLan(VLAN_ADAPTER_NAME_TAG, VLAN_CONNECTION_NAME, create->DeviceName, &ver) == false)
- {
- // Installation Failed
- FreeKakushi(k);
- CiSetError(c, ERR_VLAN_INSTALL_ERROR);
- CiNotify(c);
- CiSendGlobalPulse(c);
- return false;
- }
- }
- else
- {
- // Perform the installation (Windows Vista)
- char tmp[MAX_SIZE];
- Format(tmp, sizeof(tmp), "instvlan %s", create->DeviceName);
- if (CncExecDriverInstaller(tmp) == false)
- {
- // Installation Failed
- FreeKakushi(k);
- CiSetError(c, ERR_VLAN_INSTALL_ERROR);
- CiNotify(c);
- CiSendGlobalPulse(c);
- return false;
- }
- }
- FreeKakushi(k);
- t = MsEnumNetworkAdapters(VLAN_ADAPTER_NAME, VLAN_ADAPTER_NAME_OLD);
- if (t->NumTokens == 1)
- {
- UINT i;
- // If the result of the installation, virtual LAN card is only one,
- // set virtual LAN card setting of all existing accounts to this virtual LAN card
- LockList(c->AccountList);
- {
- for (i = 0;i < LIST_NUM(c->AccountList);i++)
- {
- ACCOUNT *a = LIST_DATA(c->AccountList, i);
- Lock(a->lock);
- {
- if (a->ClientOption != NULL)
- {
- StrCpy(a->ClientOption->DeviceName, sizeof(a->ClientOption->DeviceName), create->DeviceName);
- }
- }
- Unlock(a->lock);
- }
- }
- UnlockList(c->AccountList);
- }
- FreeToken(t);
- CLog(c, "LC_CREATE_VLAN", create->DeviceName);
- CiNormalizeAccountVLan(c);
- CiNotify(c);
- CiSendGlobalPulse(c);
- CiSaveConfigurationFile(c);
- if (MsIsNt() == false)
- {
- if (GetOsInfo()->OsType == OSTYPE_WINDOWS_ME)
- {
- // Show the warning in the case of Windows Me
- MsgBox(NULL, 0x00000040L, _UU("CM_9X_VLAN_ME_MESSAGE"));
- }
- ReleaseThread(NewThread(Win9xRebootThread, NULL));
- }
- return true;
- #endif // OS_WIN32
- }
- // Enumerate objects in the secure device
- bool CtEnumObjectInSecure(CLIENT *c, RPC_ENUM_OBJECT_IN_SECURE *e)
- {
- UINT i;
- // Validate arguments
- if (c == NULL || e == NULL)
- {
- return false;
- }
- e->NumItem = 5;
- e->ItemName = ZeroMalloc(sizeof(char *) * e->NumItem);
- e->ItemType = ZeroMalloc(sizeof(bool) * e->NumItem);
- for (i = 0;i < e->NumItem;i++)
- {
- char tmp[MAX_SIZE];
- Format(tmp, sizeof(tmp), "Test Object %u", i);
- e->ItemName[i] = CopyStr(tmp);
- e->ItemType[i] = (i % 2 == 0) ? false : true;
- }
- return true;
- }
- // Get the secure device to be used
- bool CtGetUseSecure(CLIENT *c, RPC_USE_SECURE *sec)
- {
- // Validate arguments
- if (c == NULL || sec == NULL)
- {
- return false;
- }
- sec->DeviceId = c->UseSecureDeviceId;
- return true;
- }
- // Specifying a secure device to be used
- bool CtUseSecure(CLIENT *c, RPC_USE_SECURE *sec)
- {
- // Validate arguments
- if (c == NULL || sec == NULL)
- {
- return false;
- }
- // Do not check whether there is the specified device on the client manager
- /* if (CheckSecureDeviceId(sec->DeviceId))
- {
- c->UseSecureDeviceId = sec->DeviceId;
- }
- else
- {
- CiSetError(c, ERR_OBJECT_NOT_FOUND);
- return false;
- }
- */
- c->UseSecureDeviceId = sec->DeviceId;
- CiSaveConfigurationFile(c);
- return true;
- }
- // Enumeration of secure devices
- bool CtEnumSecure(CLIENT *c, RPC_CLIENT_ENUM_SECURE *e)
- {
- LIST *o;
- UINT i;
- // Validate arguments
- if (c == NULL || e == NULL)
- {
- return false;
- }
- o = GetSecureDeviceList();
- e->NumItem = LIST_NUM(o);
- e->Items = ZeroMalloc(sizeof(RPC_CLIENT_ENUM_SECURE_ITEM *) * e->NumItem);
- for (i = 0;i < LIST_NUM(o);i++)
- {
- RPC_CLIENT_ENUM_SECURE_ITEM *item = ZeroMalloc(sizeof(RPC_CLIENT_ENUM_SECURE_ITEM));
- SECURE_DEVICE *s = LIST_DATA(o, i);
- item->DeviceId = s->Id;
- StrCpy(item->DeviceName, sizeof(item->DeviceName), s->DeviceName);
- StrCpy(item->Manufacturer, sizeof(item->Manufacturer), s->Manufacturer);
- item->Type = s->Type;
- e->Items[i] = item;
- }
- return true;
- }
- // Release the secure device enumeration
- void CiFreeClientEnumSecure(RPC_CLIENT_ENUM_SECURE *e)
- {
- UINT i;
- // Validate arguments
- if (e == NULL)
- {
- return;
- }
- for (i = 0;i < e->NumItem;i++)
- {
- Free(e->Items[i]);
- }
- Free(e->Items);
- }
- // Release the RPC_GET_ISSUER
- void CiFreeGetIssuer(RPC_GET_ISSUER *a)
- {
- // Validate arguments
- if (a == NULL)
- {
- return;
- }
- if (a->issuer_x != NULL)
- {
- FreeX(a->issuer_x);
- }
- if (a->x != NULL)
- {
- FreeX(a->x);
- }
- }
- // Get the common proxy settings
- bool CtGetCommonProxySetting(CLIENT *c, INTERNET_SETTING *a)
- {
- // Validate arguments
- if (c == NULL || a == NULL)
- {
- return false;
- }
- Copy(a, &c->CommonProxySetting, sizeof(INTERNET_SETTING));
- return true;
- }
- // Set the common proxy settings
- bool CtSetCommonProxySetting(CLIENT *c, INTERNET_SETTING *a)
- {
- // Validate arguments
- if (c == NULL || a == NULL)
- {
- return false;
- }
- Copy(&c->CommonProxySetting, a, sizeof(INTERNET_SETTING));
- CiSaveConfigurationFile(c);
- return true;
- }
- // Get the issuer
- bool CtGetIssuer(CLIENT *c, RPC_GET_ISSUER *a)
- {
- X *x;
- // Validate arguments
- if (c == NULL || a == NULL)
- {
- return false;
- }
- x = FindCaSignedX(c->Cedar->CaList, a->x);
- if (x == NULL)
- {
- CiSetError(c, ERR_OBJECT_NOT_FOUND);;
- return false;
- }
- else
- {
- a->issuer_x = x;
- if (a->x != NULL)
- {
- FreeX(a->x);
- a->x = NULL;
- }
- return true;
- }
- }
- // Get the CA certificate
- bool CtGetCa(CLIENT *c, RPC_GET_CA *get)
- {
- bool ret = true;
- X *cert = NULL;
- // Validate arguments
- if (c == NULL || get == NULL)
- {
- return false;
- }
- LockList(c->Cedar->CaList);
- {
- UINT i;
- for (i = 0;i < LIST_NUM(c->Cedar->CaList);i++)
- {
- X *x = LIST_DATA(c->Cedar->CaList, i);
- if (POINTER_TO_KEY(x) == get->Key)
- {
- cert = CloneX(x);
- break;
- }
- }
- }
- UnlockList(c->Cedar->CaList);
- if (cert == NULL)
- {
- // Certificate does not exist
- ret = false;
- CiSetError(c, ERR_OBJECT_NOT_FOUND);
- }
- else
- {
- ret = true;
- get->x = cert;
- }
- return ret;
- }
- // Delete the CA certificate
- bool CtDeleteCa(CLIENT *c, RPC_CLIENT_DELETE_CA *p)
- {
- bool ret;
- // Validate arguments
- if (c == NULL || p == NULL)
- {
- return false;
- }
- ret = DeleteCa(c->Cedar, p->Key);
- if (ret == false)
- {
- CiSetError(c, ERR_OBJECT_NOT_FOUND);
- }
- CiSaveConfigurationFile(c);
- return ret;
- }
- // Add a CA certificate
- bool CtAddCa(CLIENT *c, RPC_CERT *cert)
- {
- // Validate arguments
- if (c == NULL || cert == NULL)
- {
- return false;
- }
- if (cert->x->is_compatible_bit == false)
- {
- CiSetError(c, ERR_NOT_RSA_1024);
- return false;
- }
- AddCa(c->Cedar, cert->x);
- CiSaveConfigurationFile(c);
- return true;
- }
- // Enumerate the trusted CA
- bool CtEnumCa(CLIENT *c, RPC_CLIENT_ENUM_CA *e)
- {
- // Validate arguments
- if (c == NULL || e == NULL)
- {
- return false;
- }
- Zero(e, sizeof(RPC_CLIENT_ENUM_CA));
- LockList(c->Cedar->CaList);
- {
- UINT i;
- e->NumItem = LIST_NUM(c->Cedar->CaList);
- e->Items = ZeroMalloc(sizeof(RPC_CLIENT_ENUM_CA_ITEM *) * e->NumItem);
- for (i = 0;i < e->NumItem;i++)
- {
- X *x = LIST_DATA(c->Cedar->CaList, i);
- e->Items[i] = ZeroMalloc(sizeof(RPC_CLIENT_ENUM_CA_ITEM));
- GetAllNameFromNameEx(e->Items[i]->SubjectName, sizeof(e->Items[i]->SubjectName), x->subject_name);
- GetAllNameFromNameEx(e->Items[i]->IssuerName, sizeof(e->Items[i]->IssuerName), x->issuer_name);
- e->Items[i]->Expires = x->notAfter;
- e->Items[i]->Key = POINTER_TO_KEY(x);
- }
- }
- UnlockList(c->Cedar->CaList);
- return true;
- }
- // Release the CA enumeration
- void CiFreeClientEnumCa(RPC_CLIENT_ENUM_CA *e)
- {
- UINT i;
- // Validate arguments
- if (e == NULL)
- {
- return;
- }
- for (i = 0;i < e->NumItem;i++)
- {
- RPC_CLIENT_ENUM_CA_ITEM *ca = e->Items[i];
- Free(ca);
- }
- Free(e->Items);
- }
- // Get the password setting
- bool CtGetPasswordSetting(CLIENT *c, RPC_CLIENT_PASSWORD_SETTING *a)
- {
- UCHAR hash[SHA1_SIZE];
- // Validate arguments
- if (c == NULL || a == NULL)
- {
- return false;
- }
- Hash(hash, "", 0, true);
- if (Cmp(hash, c->EncryptedPassword, SHA1_SIZE) == 0)
- {
- a->IsPasswordPresented = false;
- }
- else
- {
- a->IsPasswordPresented = true;
- }
- a->PasswordRemoteOnly = c->PasswordRemoteOnly;
- return true;
- }
- // Set the password
- bool CtSetPassword(CLIENT *c, RPC_CLIENT_PASSWORD *pass)
- {
- char *str;
- if (c == NULL)
- {
- return false;
- }
- if (pass->Password == NULL)
- {
- str = "";
- }
- else
- {
- str = pass->Password;
- }
- if (StrCmp(str, "********") != 0)
- {
- // Hash the password
- Hash(c->EncryptedPassword, str, StrLen(str), true);
- }
- c->PasswordRemoteOnly = pass->PasswordRemoteOnly;
- CLog(c, "LC_SET_PASSWORD");
- CiSaveConfigurationFile(c);
- return true;
- }
- void CiFreeIni(LIST *o)
- {
- // Validate arguments
- if (o == NULL)
- {
- return;
- }
- FreeIni(o);
- }
- // Read the custom.ini file
- LIST *CiLoadIni()
- {
- BUF *b = ReadDump(CLIENT_CUSTOM_INI_FILENAME);
- LIST *ini;
- if (b == NULL)
- {
- return NULL;
- }
- ini = ReadIni(b);
- FreeBuf(b);
- return ini;
- }
- // Reflect the settings of the custom.ini
- void CiLoadIniSettings(CLIENT *c)
- {
- LIST *o;
- //char *log;
- //char *config;
- if (c == NULL)
- {
- return;
- }
- o = CiLoadIni();
- if (o == NULL)
- {
- return;
- }
- /*log = IniStrValue(o, "NoSaveLog");
- config = IniStrValue(o, "NoSaveConfig");
- if(StrCmpi(log, "true") == 0)
- {
- c->NoSaveLog = true;
- }
- if(StrCmpi(config, "true") == 0)
- {
- c->NoSaveConfig = true;
- }*/
- c->NoSaveLog = ToBool(IniStrValue(o, "NoSaveLog"));
- c->NoSaveConfig = ToBool(IniStrValue(o, "NoSaveConfig"));
-
- CiFreeIni(o);
- }
- bool CiLoadConfigFilePathFromIni(char *path, UINT size)
- {
- char *tmp;
- LIST *o;
- bool ret = false;
- // Validate arguments
- if (path == NULL)
- {
- return false;
- }
- o = CiLoadIni();
- if (o == NULL)
- {
- return false;
- }
- StrCpy(path, size, "");
- tmp = IniStrValue(o, "ConfigPath");
- NormalizePath(path, size, tmp);
- if (IsEmptyStr(path) == false)
- {
- ret = true;
- }
- else
- {
- ret = false;
- }
- CiFreeIni(o);
- return ret;
- }
- // Set the client error code
- void CiSetError(CLIENT *c, UINT err)
- {
- // Validate arguments
- if (c == NULL)
- {
- return;
- }
- c->Err = err;
- }
- // UNIX virtual LAN card comparison function
- int CiCompareUnixVLan(void *p1, void *p2)
- {
- UNIX_VLAN *v1, *v2;
- if (p1 == NULL || p2 == NULL)
- {
- return 0;
- }
- v1 = *(UNIX_VLAN **)p1;
- v2 = *(UNIX_VLAN **)p2;
- if (v1 == NULL || v2 == NULL)
- {
- return 0;
- }
- return StrCmpi(v1->Name, v2->Name);
- }
- // Modify the account settings that an incorrect VLAN name is specified
- void CiNormalizeAccountVLan(CLIENT *c)
- {
- bool b = false;
- char *name;
- UINT i;
- // Validate arguments
- if (c == NULL)
- {
- return;
- }
- name = CiGetFirstVLan(c);
- if (name != NULL)
- {
- LockList(c->AccountList);
- {
- for (i = 0;i < LIST_NUM(c->AccountList);i++)
- {
- ACCOUNT *a = LIST_DATA(c->AccountList, i);
- Lock(a->lock);
- {
- if (a->ClientOption != NULL)
- {
- if (CiIsVLan(c, a->ClientOption->DeviceName) == false)
- {
- StrCpy(a->ClientOption->DeviceName, sizeof(a->ClientOption->DeviceName),
- name);
- b = true;
- }
- }
- }
- Unlock(a->lock);
- }
- }
- UnlockList(c->AccountList);
- Free(name);
- }
- if (b)
- {
- CiNotify(c);
- CiSendGlobalPulse(c);
- CiSaveConfigurationFile(c);
- }
- }
- // Check whether a virtual LAN card of the specified name exists
- bool CiIsVLan(CLIENT *c, char *name)
- {
- // Validate arguments
- if (c == NULL || name == NULL)
- {
- return false;
- }
- #ifdef OS_WIN32
- {
- TOKEN_LIST *t;
- UINT i;
- t = MsEnumNetworkAdapters(VLAN_ADAPTER_NAME, VLAN_ADAPTER_NAME_OLD);
- if (t == NULL)
- {
- return false;
- }
- for (i = 0;i < t->NumTokens;i++)
- {
- if (StrCmpi(t->Token[i], name) == 0)
- {
- FreeToken(t);
- return true;
- }
- }
- FreeToken(t);
- return false;
- }
- #else // OS_WIN32
- {
- UNIX_VLAN *v;
- UINT i;
- bool ret = false;
- LockList(c->UnixVLanList);
- {
- for (i = 0;i < LIST_NUM(c->UnixVLanList);i++)
- {
- v = (UNIX_VLAN *)LIST_DATA(c->UnixVLanList, i);
- if (StrCmpi(v->Name, name) == 0)
- {
- ret = true;
- }
- }
- }
- UnlockList(c->UnixVLanList);
- return ret;
- }
- #endif // OS_WIN32
- }
- // If a non-existent virtual LAN card is specified in any Account, and only
- // one virtual LAN card is installed, set the virtual LAN card to the account
- void CiSetVLanToDefault(CLIENT *c)
- {
- char device_name[MAX_SIZE];
- // Validate arguments
- if (c == NULL)
- {
- return;
- }
- #ifdef OS_WIN32
- {
- TOKEN_LIST *t;
- t = MsEnumNetworkAdapters(VLAN_ADAPTER_NAME, VLAN_ADAPTER_NAME_OLD);
- if (t == NULL)
- {
- return;
- }
- if (t->NumTokens != 1)
- {
- FreeToken(t);
- return;
- }
- StrCpy(device_name, sizeof(device_name), t->Token[0]);
- FreeToken(t);
- }
- #else // OS_WIN32
- {
- UINT i;
- UNIX_VLAN *v;
- LockList(c->UnixVLanList);
- if (LIST_NUM(c->UnixVLanList) != 1)
- {
- UnlockList(c->UnixVLanList);
- return;
- }
- v = LIST_DATA(c->UnixVLanList, 0);
- StrCpy(device_name, sizeof(device_name), v->Name);
- UnlockList(c->UnixVLanList);
- }
- #endif // OS_WIN32
- {
- UINT i;
- LockList(c->AccountList);
- {
- for (i = 0;i < LIST_NUM(c->AccountList);i++)
- {
- ACCOUNT *a = LIST_DATA(c->AccountList, i);
- Lock(a->lock);
- {
- if (CiIsVLan(c, a->ClientOption->DeviceName) == false)
- {
- StrCpy(a->ClientOption->DeviceName, sizeof(a->ClientOption->DeviceName),
- device_name);
- }
- }
- Unlock(a->lock);
- }
- }
- UnlockList(c->AccountList);
- }
- }
- // Initialize the settings
- void CiInitConfiguration(CLIENT *c)
- {
- // Validate arguments
- if (c == NULL)
- {
- return;
- }
- #ifdef OS_UNIX
- // Initialize the VLAN
- UnixVLanInit();
- #endif // OS_UNIX
- // Account list
- c->AccountList = NewList(CiCompareAccount);
- // Unix version VLAN list
- if (OS_IS_UNIX(GetOsInfo()->OsType))
- {
- c->UnixVLanList = NewList(CiCompareUnixVLan);
- }
- // Read the configuration file
- CLog(c, "LC_LOAD_CONFIG_1");
- if (CiLoadConfigurationFile(c) == false)
- {
- CLog(c, "LC_LOAD_CONFIG_3");
- // Do the initial setup because the configuration file does not exist
- // Clear the password
- Hash(c->EncryptedPassword, "", 0, true);
- // Initialize the client configuration
- if (OS_IS_WINDOWS(GetOsInfo()->OsType))
- {
- // Disable remote management in Windows
- c->Config.AllowRemoteConfig = false;
- }
- else
- {
- // Disable the remote management also in case of UNIX
- c->Config.AllowRemoteConfig = false;
- }
- StrCpy(c->Config.KeepConnectHost, sizeof(c->Config.KeepConnectHost), CLIENT_DEFAULT_KEEPALIVE_HOST);
- c->Config.KeepConnectPort = CLIENT_DEFAULT_KEEPALIVE_PORT;
- c->Config.KeepConnectProtocol = CONNECTION_UDP;
- c->Config.KeepConnectInterval = CLIENT_DEFAULT_KEEPALIVE_INTERVAL;
- c->Config.UseKeepConnect = false; // Don't use the connection maintenance function by default in the Client
- // Eraser
- c->Eraser = NewEraser(c->Logger, 0);
- }
- else
- {
- CLog(c, "LC_LOAD_CONFIG_2");
- }
- // Appropriate setting for virtual LAN card
- CiSetVLanToDefault(c);
- }
- // Release the settings
- void CiFreeConfiguration(CLIENT *c)
- {
- UINT i;
- // Validate arguments
- if (c == NULL)
- {
- return;
- }
- // Write to the configuration file
- CiSaveConfigurationFile(c);
- // Release the configuration file
- FreeCfgRw(c->CfgRw);
- // Release the account list
- for (i = 0;i < LIST_NUM(c->AccountList);i++)
- {
- ACCOUNT *a = LIST_DATA(c->AccountList, i);
- CiFreeAccount(a);
- }
- ReleaseList(c->AccountList);
- if (c->UnixVLanList != NULL)
- {
- // Release of UNIX version VLAN list
- for (i = 0;i < LIST_NUM(c->UnixVLanList);i++)
- {
- UNIX_VLAN *v = LIST_DATA(c->UnixVLanList, i);
- Free(v);
- }
- ReleaseList(c->UnixVLanList);
- }
- c->UnixVLanList = NULL;
- #ifdef OS_UNIX
- // Release the VLAN
- UnixVLanFree();
- #endif // OS_UNIX
- }
- // Release the certificate data acquisition
- void CiFreeGetCa(RPC_GET_CA *a)
- {
- // Validate arguments
- if (a == NULL)
- {
- return;
- }
- FreeX(a->x);
- }
- // Release the client authentication data
- void CiFreeClientAuth(CLIENT_AUTH *auth)
- {
- // Validate arguments
- if (auth == NULL)
- {
- return;
- }
- if (auth->ClientX != NULL)
- {
- FreeX(auth->ClientX);
- }
- if (auth->ClientK != NULL)
- {
- FreeK(auth->ClientK);
- }
- Free(auth);
- }
- // Release the account
- void CiFreeAccount(ACCOUNT *a)
- {
- // Validate arguments
- if (a == NULL)
- {
- return;
- }
- // Release the lock
- DeleteLock(a->lock);
- // Release the client option
- Free(a->ClientOption);
- // Release the client authentication data
- CiFreeClientAuth(a->ClientAuth);
- if (a->ServerCert != NULL)
- {
- FreeX(a->ServerCert);
- }
- Free(a);
- }
- // Sort accounts
- int CiCompareAccount(void *p1, void *p2)
- {
- ACCOUNT *a1, *a2;
- if (p1 == NULL || p2 == NULL)
- {
- return 0;
- }
- a1 = *(ACCOUNT **)p1;
- a2 = *(ACCOUNT **)p2;
- if (a1 == NULL || a2 == NULL)
- {
- return 0;
- }
- return UniStrCmpi(a1->ClientOption->AccountName, a2->ClientOption->AccountName);
- }
- // Read the client configuration
- void CiLoadClientConfig(CLIENT_CONFIG *c, FOLDER *f)
- {
- // Validate arguments
- if (c == NULL || f == NULL)
- {
- return;
- }
- c->UseKeepConnect = CfgGetBool(f, "UseKeepConnect");
- CfgGetStr(f, "KeepConnectHost", c->KeepConnectHost, sizeof(c->KeepConnectHost));
- c->KeepConnectPort = CfgGetInt(f, "KeepConnectPort");
- c->KeepConnectProtocol = CfgGetInt(f, "KeepConnectProtocol");
- c->AllowRemoteConfig = CfgGetBool(f, "AllowRemoteConfig");
- c->KeepConnectInterval = MAKESURE(CfgGetInt(f, "KeepConnectInterval"), KEEP_INTERVAL_MIN, KEEP_INTERVAL_MAX);
- c->NoChangeWcmNetworkSettingOnWindows8 = CfgGetBool(f, "NoChangeWcmNetworkSettingOnWindows8");
- }
- // Read the client authentication data
- CLIENT_AUTH *CiLoadClientAuth(FOLDER *f)
- {
- CLIENT_AUTH *a;
- char *s;
- BUF *b;
- // Validate arguments
- if (f == NULL)
- {
- return NULL;
- }
- a = ZeroMalloc(sizeof(CLIENT_AUTH));
- a->AuthType = CfgGetInt(f, "AuthType");
- CfgGetStr(f, "Username", a->Username, sizeof(a->Username));
- switch (a->AuthType)
- {
- case CLIENT_AUTHTYPE_ANONYMOUS:
- break;
- case CLIENT_AUTHTYPE_PASSWORD:
- CfgGetByte(f, "HashedPassword", a->HashedPassword, SHA1_SIZE);
- break;
- case CLIENT_AUTHTYPE_PLAIN_PASSWORD:
- b = CfgGetBuf(f, "EncryptedPassword");
- if (b != NULL)
- {
- s = DecryptPassword(b);
- StrCpy(a->PlainPassword, sizeof(a->PlainPassword), s);
- Free(s);
- FreeBuf(b);
- }
- break;
- case CLIENT_AUTHTYPE_CERT:
- b = CfgGetBuf(f, "ClientCert");
- if (b != NULL)
- {
- a->ClientX = BufToX(b, false);
- }
- FreeBuf(b);
- b = CfgGetBuf(f, "ClientKey");
- if (b != NULL)
- {
- a->ClientK = BufToK(b, true, false, NULL);
- }
- FreeBuf(b);
- break;
- case CLIENT_AUTHTYPE_SECURE:
- CfgGetStr(f, "SecurePublicCertName", a->SecurePublicCertName, sizeof(a->SecurePublicCertName));
- CfgGetStr(f, "SecurePrivateKeyName", a->SecurePrivateKeyName, sizeof(a->SecurePrivateKeyName));
- break;
- }
- return a;
- }
- // Read the client option
- CLIENT_OPTION *CiLoadClientOption(FOLDER *f)
- {
- CLIENT_OPTION *o;
- char *s;
- BUF *b;
- // Validate arguments
- if (f == NULL)
- {
- return NULL;
- }
- o = ZeroMalloc(sizeof(CLIENT_OPTION));
- CfgGetUniStr(f, "AccountName", o->AccountName, sizeof(o->AccountName));
- CfgGetStr(f, "Hostname", o->Hostname, sizeof(o->Hostname));
- o->Port = CfgGetInt(f, "Port");
- o->PortUDP = CfgGetInt(f, "PortUDP");
- o->ProxyType = CfgGetInt(f, "ProxyType");
- CfgGetStr(f, "ProxyName", o->ProxyName, sizeof(o->ProxyName));
- o->ProxyPort = CfgGetInt(f, "ProxyPort");
- CfgGetStr(f, "ProxyUsername", o->ProxyUsername, sizeof(o->ProxyUsername));
- b = CfgGetBuf(f, "ProxyPassword");
- s = DecryptPassword(b);
- StrCpy(o->ProxyPassword, sizeof(o->ProxyPassword), s);
- Free(s);
- FreeBuf(b);
- o->NumRetry = CfgGetInt(f, "NumRetry");
- o->RetryInterval = CfgGetInt(f, "RetryInterval");
- CfgGetStr(f, "HubName", o->HubName, sizeof(o->HubName));
- o->MaxConnection = CfgGetInt(f, "MaxConnection");
- o->UseEncrypt = CfgGetBool(f, "UseEncrypt");
- o->UseCompress = CfgGetBool(f, "UseCompress");
- o->HalfConnection = CfgGetBool(f, "HalfConnection");
- o->NoRoutingTracking = CfgGetBool(f, "NoRoutingTracking");
- CfgGetStr(f, "DeviceName", o->DeviceName, sizeof(o->DeviceName));
- o->AdditionalConnectionInterval = CfgGetInt(f, "AdditionalConnectionInterval");
- o->HideStatusWindow = CfgGetBool(f, "HideStatusWindow");
- o->HideNicInfoWindow = CfgGetBool(f, "HideNicInfoWindow");
- o->ConnectionDisconnectSpan = CfgGetInt(f, "ConnectionDisconnectSpan");
- o->RequireMonitorMode = CfgGetBool(f, "RequireMonitorMode");
- o->RequireBridgeRoutingMode = CfgGetBool(f, "RequireBridgeRoutingMode");
- o->DisableQoS = CfgGetBool(f, "DisableQoS");
- o->FromAdminPack = CfgGetBool(f, "FromAdminPack");
- o->NoTls1 = CfgGetBool(f, "NoTls1");
- o->NoUdpAcceleration = CfgGetBool(f, "NoUdpAcceleration");
-
- b = CfgGetBuf(f, "HostUniqueKey");
- if (b != NULL)
- {
- if (b->Size == SHA1_SIZE)
- {
- Copy(o->HostUniqueKey, b->Buf, SHA1_SIZE);
- }
- FreeBuf(b);
- }
- return o;
- }
- // Read the account data
- ACCOUNT *CiLoadClientAccount(FOLDER *f)
- {
- ACCOUNT *a;
- FOLDER *client_option_folder, *client_auth_folder;
- BUF *b;
- char tmp[64];
- // Validate arguments
- if (f == NULL)
- {
- return NULL;
- }
- client_option_folder = CfgGetFolder(f, "ClientOption");
- if (client_option_folder != NULL)
- {
- // Compare whether it matches to the account name that is already registered
- }
- client_auth_folder = CfgGetFolder(f, "ClientAuth");
- if (client_option_folder == NULL || client_auth_folder == NULL)
- {
- return NULL;
- }
- a = ZeroMalloc(sizeof(ACCOUNT));
- a->lock = NewLock();
- a->ClientOption = CiLoadClientOption(client_option_folder);
- a->ClientAuth = CiLoadClientAuth(client_auth_folder);
- a->StartupAccount = CfgGetBool(f, "StartupAccount");
- a->CheckServerCert = CfgGetBool(f, "CheckServerCert");
- a->CreateDateTime = CfgGetInt64(f, "CreateDateTime");
- a->UpdateDateTime = CfgGetInt64(f, "UpdateDateTime");
- a->LastConnectDateTime = CfgGetInt64(f, "LastConnectDateTime");
- b = CfgGetBuf(f, "ServerCert");
- if (b != NULL)
- {
- a->ServerCert = BufToX(b, false);
- FreeBuf(b);
- }
- if (CfgGetStr(f, "ShortcutKey", tmp, sizeof(tmp)))
- {
- BUF *b = StrToBin(tmp);
- if (b->Size == SHA1_SIZE)
- {
- Copy(a->ShortcutKey, b->Buf, SHA1_SIZE);
- }
- FreeBuf(b);
- }
- if (IsZero(a->ShortcutKey, SHA1_SIZE))
- {
- Rand(a->ShortcutKey, SHA1_SIZE);
- }
- return a;
- }
- // Read the account database
- void CiLoadAccountDatabase(CLIENT *c, FOLDER *f)
- {
- TOKEN_LIST *t;
- UINT i;
- // Validate arguments
- if (c == NULL || f == NULL)
- {
- return;
- }
- t = CfgEnumFolderToTokenList(f);
- if (t == NULL)
- {
- return;
- }
- for (i = 0;i < t->NumTokens;i++)
- {
- FOLDER *ff = CfgGetFolder(f, t->Token[i]);
- if (ff != NULL)
- {
- ACCOUNT *a = CiLoadClientAccount(ff);
- if (a != NULL)
- {
- {
- Add(c->AccountList, a);
- }
- }
- }
- }
- Sort(c->AccountList);
- FreeToken(t);
- }
- // Read the root CA certificate
- void CiLoadCACert(CLIENT *c, FOLDER *f)
- {
- BUF *b;
- X *x;
- // Validate arguments
- if (c == NULL || f == NULL)
- {
- return;
- }
- b = CfgGetBuf(f, "X509");
- if (b == NULL)
- {
- return;
- }
- x = BufToX(b, false);
- AddCa(c->Cedar, x);
- FreeX(x);
- FreeBuf(b);
- }
- // Read the root CA list
- void CiLoadCAList(CLIENT *c, FOLDER *f)
- {
- CEDAR *cedar;
- TOKEN_LIST *t;
- // Validate arguments
- if (c == NULL || f == NULL)
- {
- return;
- }
- t = CfgEnumFolderToTokenList(f);
- cedar = c->Cedar;
- LockList(cedar->CaList);
- {
- UINT i;
- for (i = 0;i < t->NumTokens;i++)
- {
- FOLDER *folder = CfgGetFolder(f, t->Token[i]);
- CiLoadCACert(c, folder);
- }
- }
- UnlockList(cedar->CaList);
- FreeToken(t);
- }
- // Read a VLAN
- void CiLoadVLan(CLIENT *c, FOLDER *f)
- {
- char tmp[MAX_SIZE];
- UCHAR addr[6];
- BUF *b;
- UNIX_VLAN *v;
- // Validate arguments
- if (c == NULL || f == NULL)
- {
- return;
- }
- if (CfgGetStr(f, "MacAddress", tmp, sizeof(tmp)) == false)
- {
- return;
- }
- b = StrToBin(tmp);
- if (b == NULL)
- {
- return;
- }
- if (b->Size != 6)
- {
- FreeBuf(b);
- return;
- }
- Copy(addr, b->Buf, 6);
- FreeBuf(b);
- if (IsZero(addr, 6))
- {
- return;
- }
- v = ZeroMalloc(sizeof(UNIX_VLAN));
- Copy(v->MacAddress, addr, 6);
- StrCpy(v->Name, sizeof(v->Name), f->Name);
- v->Enabled = CfgGetBool(f, "Enabled");
- Add(c->UnixVLanList, v);
- #ifdef OS_UNIX
- UnixVLanCreate(v->Name, v->MacAddress);
- #endif // OS_UNIX
- }
- // Read a VLAN list
- void CiLoadVLanList(CLIENT *c, FOLDER *f)
- {
- TOKEN_LIST *t;
- // Validate arguments
- if (c == NULL || f == NULL)
- {
- return;
- }
- t = CfgEnumFolderToTokenList(f);
- LockList(c->UnixVLanList);
- {
- UINT i;
- for (i = 0;i < t->NumTokens;i++)
- {
- FOLDER *folder = CfgGetFolder(f, t->Token[i]);
- CiLoadVLan(c, folder);
- }
- }
- UnlockList(c->UnixVLanList);
- FreeToken(t);
- }
- // Read the configuration from the configuration file
- bool CiReadSettingFromCfg(CLIENT *c, FOLDER *root)
- {
- FOLDER *config;
- FOLDER *cert;
- FOLDER *db;
- FOLDER *vlan;
- FOLDER *cmsetting;
- FOLDER *proxy;
- char user_agent[MAX_SIZE];
- // Validate arguments
- if (c == NULL || root == NULL)
- {
- return false;
- }
- // Initialize the setting if there isn't either of AccountDatabase and Config
- config = CfgGetFolder(root, "Config");
- if (config == NULL)
- {
- return false;
- }
- db = CfgGetFolder(root, "AccountDatabase");
- if (db == NULL)
- {
- return false;
- }
- cmsetting = CfgGetFolder(root, "ClientManagerSetting");
- CiLoadClientConfig(&c->Config, config);
- proxy = CfgGetFolder(root, "CommonProxySetting");
- if (proxy != NULL)
- {
- INTERNET_SETTING t;
- BUF *pw;
- // Proxy Setting
- Zero(&t, sizeof(t));
- t.ProxyType = CfgGetInt(proxy, "ProxyType");
- CfgGetStr(proxy, "ProxyHostName", t.ProxyHostName, sizeof(t.ProxyHostName));
- t.ProxyPort = CfgGetInt(proxy, "ProxyPort");
- CfgGetStr(proxy, "ProxyUsername", t.ProxyUsername, sizeof(t.ProxyUsername));
- pw = CfgGetBuf(proxy, "ProxyPassword");
- if (pw != NULL)
- {
- char *pw_str = DecryptPassword(pw);
- StrCpy(t.ProxyPassword, sizeof(t.ProxyPassword), pw_str);
- Free(pw_str);
- FreeBuf(pw);
- }
- Copy(&c->CommonProxySetting, &t, sizeof(INTERNET_SETTING));
- }
- // Eraser
- c->Eraser = NewEraser(c->Logger, CfgGetInt64(config, "AutoDeleteCheckDiskFreeSpaceMin"));
- if (OS_IS_UNIX(GetOsInfo()->OsType)
- #ifdef NO_VLAN
- && GetOsInfo()->OsType != OSTYPE_MACOS_X
- #endif // NO_VLAN
- )
- {
- // Read the UNIX version virtual LAN card list (except MacOS)
- vlan = CfgGetFolder(root, "UnixVLan");
- if (vlan != NULL)
- {
- CiLoadVLanList(c, vlan);
- }
- }
- #ifdef NO_VLAN
- if (GetOsInfo()->OsType == OSTYPE_MACOS_X)
- {
- #ifdef OS_UNIX
- UNIX_VLAN *uv;
- // Create a Tap for MacOS X
- if (UnixVLanCreate(CLIENT_MACOS_TAP_NAME, NULL) == false)
- {
- // Fail (abort)
- CLog(c, "LC_TAP_NOT_FOUND");
- Alert("tun/tap driver not found.", NULL);
- exit(0);
- }
- uv = ZeroMalloc(sizeof(UNIX_VLAN));
- uv->Enabled = true;
- StrCpy(uv->Name, sizeof(uv->Name), CLIENT_MACOS_TAP_NAME);
- Add(c->UnixVLanList, uv);
- #endif // OS_UNIX
- }
- #endif // NO_VLAN
- CiLoadAccountDatabase(c, db);
- if (CfgGetByte(root, "EncryptedPassword", c->EncryptedPassword, SHA1_SIZE) == false)
- {
- Hash(c->EncryptedPassword, "", 0, true);
- }
- c->PasswordRemoteOnly = CfgGetBool(root, "PasswordRemoteOnly");
- c->UseSecureDeviceId = CfgGetInt(root, "UseSecureDeviceId");
- if (CfgGetStr(root, "UserAgent", user_agent, sizeof(user_agent)))
- {
- if (IsEmptyStr(user_agent) == false)
- {
- Free(c->Cedar->HttpUserAgent);
- c->Cedar->HttpUserAgent = CopyStr(user_agent);
- }
- }
- cert = CfgGetFolder(root, "RootCA");
- if (cert != NULL)
- {
- CiLoadCAList(c, cert);
- }
- c->DontSavePassword = CfgGetBool(root, "DontSavePassword");
- if (cmsetting != NULL)
- {
- UINT ostype = GetOsInfo()->OsType;
- // CM_SETTING
- CM_SETTING *s = c->CmSetting;
- if (OS_IS_UNIX(ostype) || OS_IS_WINDOWS_NT(ostype))
- {
- s->EasyMode = CfgGetBool(cmsetting, "EasyMode");
- }
- s->LockMode = CfgGetBool(cmsetting, "LockMode");
- CfgGetByte(cmsetting, "HashedPassword", s->HashedPassword, sizeof(s->HashedPassword));
- }
- return true;
- }
- // Read the configuration file
- bool CiLoadConfigurationFile(CLIENT *c)
- {
- bool ret;
- FOLDER *root;
- char path[MAX_SIZE];
- // Validate arguments
- if (c == NULL)
- {
- return false;
- }
- // Read the configuration file
- if (CiLoadConfigFilePathFromIni(path, sizeof(path)))
- {
- c->CfgRw = NewCfgRw(&root, path);
- }
- else
- {
- c->CfgRw = NewCfgRw(&root, CLIENT_CONFIG_FILE_NAME);
- }
- if (root == NULL)
- {
- return false;
- }
- ret = CiReadSettingFromCfg(c, root);
- CfgDeleteFolder(root);
- return ret;
- }
- // Write the CLIENT_CONFIG
- void CiWriteClientConfig(FOLDER *cc, CLIENT_CONFIG *config)
- {
- // Validate arguments
- if (cc == NULL || config == NULL)
- {
- return;
- }
- CfgAddBool(cc, "UseKeepConnect", config->UseKeepConnect);
- CfgAddStr(cc, "KeepConnectHost", config->KeepConnectHost);
- CfgAddInt(cc, "KeepConnectPort", config->KeepConnectPort);
- CfgAddInt(cc, "KeepConnectProtocol", config->KeepConnectProtocol);
- CfgAddBool(cc, "AllowRemoteConfig", config->AllowRemoteConfig);
- CfgAddInt(cc, "KeepConnectInterval", config->KeepConnectInterval);
- CfgAddBool(cc, "NoChangeWcmNetworkSettingOnWindows8", config->NoChangeWcmNetworkSettingOnWindows8);
- }
- // Write the client authentication data
- void CiWriteClientAuth(FOLDER *f, CLIENT_AUTH *a)
- {
- BUF *b;
- // Validate arguments
- if (f == NULL || a == NULL)
- {
- return;
- }
- CfgAddInt(f, "AuthType", a->AuthType);
- CfgAddStr(f, "Username", a->Username);
- switch (a->AuthType)
- {
- case CLIENT_AUTHTYPE_ANONYMOUS:
- break;
- case CLIENT_AUTHTYPE_PASSWORD:
- CfgAddByte(f, "HashedPassword", a->HashedPassword, SHA1_SIZE);
- break;
- case CLIENT_AUTHTYPE_PLAIN_PASSWORD:
- b = EncryptPassword(a->PlainPassword);
- CfgAddByte(f, "EncryptedPassword", b->Buf, b->Size);
- FreeBuf(b);
- break;
- case CLIENT_AUTHTYPE_CERT:
- if (a->ClientK != NULL && a->ClientX != NULL)
- {
- b = XToBuf(a->ClientX, false);
- CfgAddByte(f, "ClientCert", b->Buf, b->Size);
- FreeBuf(b);
- b = KToBuf(a->ClientK, false, NULL);
- CfgAddByte(f, "ClientKey", b->Buf, b->Size);
- FreeBuf(b);
- }
- break;
- case CLIENT_AUTHTYPE_SECURE:
- CfgAddStr(f, "SecurePublicCertName", a->SecurePublicCertName);
- CfgAddStr(f, "SecurePrivateKeyName", a->SecurePrivateKeyName);
- break;
- }
- }
- // Write the client option
- void CiWriteClientOption(FOLDER *f, CLIENT_OPTION *o)
- {
- BUF *b;
- // Validate arguments
- if (f == NULL || o == NULL)
- {
- return;
- }
- CfgAddUniStr(f, "AccountName", o->AccountName);
- CfgAddStr(f, "Hostname", o->Hostname);
- CfgAddInt(f, "Port", o->Port);
- CfgAddInt(f, "PortUDP", o->PortUDP);
- CfgAddInt(f, "ProxyType", o->ProxyType);
- CfgAddStr(f, "ProxyName", o->ProxyName);
- CfgAddInt(f, "ProxyPort", o->ProxyPort);
- CfgAddStr(f, "ProxyUsername", o->ProxyUsername);
- b = EncryptPassword(o->ProxyPassword);
- CfgAddByte(f, "ProxyPassword", b->Buf, b->Size);
- FreeBuf(b);
- CfgAddInt(f, "NumRetry", o->NumRetry);
- CfgAddInt(f, "RetryInterval", o->RetryInterval);
- CfgAddStr(f, "HubName", o->HubName);
- CfgAddInt(f, "MaxConnection", o->MaxConnection);
- CfgAddBool(f, "UseEncrypt", o->UseEncrypt);
- CfgAddBool(f, "UseCompress", o->UseCompress);
- CfgAddBool(f, "HalfConnection", o->HalfConnection);
- CfgAddBool(f, "NoRoutingTracking", o->NoRoutingTracking);
- CfgAddStr(f, "DeviceName", o->DeviceName);
- CfgAddInt(f, "AdditionalConnectionInterval", o->AdditionalConnectionInterval);
- CfgAddBool(f, "HideStatusWindow", o->HideStatusWindow);
- CfgAddBool(f, "HideNicInfoWindow", o->HideNicInfoWindow);
- CfgAddInt(f, "ConnectionDisconnectSpan", o->ConnectionDisconnectSpan);
- CfgAddBool(f, "RequireMonitorMode", o->RequireMonitorMode);
- CfgAddBool(f, "RequireBridgeRoutingMode", o->RequireBridgeRoutingMode);
- CfgAddBool(f, "DisableQoS", o->DisableQoS);
- CfgAddBool(f, "NoTls1", o->NoTls1);
- CfgAddBool(f, "NoUdpAcceleration", o->NoUdpAcceleration);
- if (o->FromAdminPack)
- {
- CfgAddBool(f, "FromAdminPack", o->FromAdminPack);
- }
- if (IsZero(o->HostUniqueKey, SHA1_SIZE) == false)
- {
- BUF *b = MemToBuf(o->HostUniqueKey, SHA1_SIZE);
- CfgAddBuf(f, "HostUniqueKey", b);
- FreeBuf(b);
- }
- }
- // Decrypt the password
- char *DecryptPassword(BUF *b)
- {
- char *str;
- char *key = "EncryptPassword";
- CRYPT *c;
- // Validate arguments
- if (b == NULL)
- {
- return CopyStr("");
- }
- str = ZeroMalloc(b->Size + 1);
- c = NewCrypt(key, sizeof(key));
- Encrypt(c, str, b->Buf, b->Size);
- FreeCrypt(c);
- str[b->Size] = 0;
- return str;
- }
- char *DecryptPassword2(BUF *b)
- {
- char *str;
- char *key = "EncryptPassword2";
- CRYPT *c;
- // Validate arguments
- if (b == NULL)
- {
- return CopyStr("");
- }
- str = ZeroMalloc(b->Size + 1);
- c = NewCrypt(key, StrLen(key));
- Encrypt(c, str, b->Buf, b->Size);
- FreeCrypt(c);
- str[b->Size] = 0;
- return str;
- }
- // Encrypt the password
- BUF *EncryptPassword(char *password)
- {
- UCHAR *tmp;
- UINT size;
- char *key = "EncryptPassword";
- CRYPT *c;
- BUF *b;
- // Validate arguments
- if (password == NULL)
- {
- password = "";
- }
- size = StrLen(password) + 1;
- tmp = ZeroMalloc(size);
- c = NewCrypt(key, sizeof(key));
- Encrypt(c, tmp, password, size - 1);
- FreeCrypt(c);
- b = NewBuf();
- WriteBuf(b, tmp, size - 1);
- SeekBuf(b, 0, 0);
- Free(tmp);
- return b;
- }
- BUF *EncryptPassword2(char *password)
- {
- UCHAR *tmp;
- UINT size;
- char *key = "EncryptPassword2";
- CRYPT *c;
- BUF *b;
- // Validate arguments
- if (password == NULL)
- {
- password = "";
- }
- size = StrLen(password) + 1;
- tmp = ZeroMalloc(size);
- c = NewCrypt(key, StrLen(key));
- Encrypt(c, tmp, password, size - 1);
- FreeCrypt(c);
- b = NewBuf();
- WriteBuf(b, tmp, size - 1);
- SeekBuf(b, 0, 0);
- Free(tmp);
- return b;
- }
- // Write the account data
- void CiWriteAccountData(FOLDER *f, ACCOUNT *a)
- {
- // Validate arguments
- if (f == NULL || a == NULL)
- {
- return;
- }
- // Client Option
- CiWriteClientOption(CfgCreateFolder(f, "ClientOption"), a->ClientOption);
- // Client authentication data
- CiWriteClientAuth(CfgCreateFolder(f, "ClientAuth"), a->ClientAuth);
- // Startup account
- CfgAddBool(f, "StartupAccount", a->StartupAccount);
- // Server certificate check flag
- CfgAddBool(f, "CheckServerCert", a->CheckServerCert);
- // Date and time
- CfgAddInt64(f, "CreateDateTime", a->CreateDateTime);
- CfgAddInt64(f, "UpdateDateTime", a->UpdateDateTime);
- CfgAddInt64(f, "LastConnectDateTime", a->LastConnectDateTime);
- // Server certificate body
- if (a->ServerCert != NULL)
- {
- BUF *b = XToBuf(a->ServerCert, false);
- if (b != NULL)
- {
- CfgAddBuf(f, "ServerCert", b);
- FreeBuf(b);
- }
- }
- // Shortcut Key
- if (IsZero(a->ShortcutKey, SHA1_SIZE) == false)
- {
- char tmp[64];
- BinToStr(tmp, sizeof(tmp), a->ShortcutKey, SHA1_SIZE);
- CfgAddStr(f, "ShortcutKey", tmp);
- }
- }
- // Write the account database
- void CiWriteAccountDatabase(CLIENT *c, FOLDER *f)
- {
- char name[MAX_SIZE];
- // Validate arguments
- if (c == NULL || f == NULL)
- {
- return;
- }
- LockList(c->AccountList);
- {
- UINT i;
- for (i = 0;i < LIST_NUM(c->AccountList);i++)
- {
- ACCOUNT *a = LIST_DATA(c->AccountList, i);
- {
- Format(name, sizeof(name), "Account%u", i);
- Lock(a->lock);
- {
- CiWriteAccountData(CfgCreateFolder(f, name), a);
- }
- Unlock(a->lock);
- }
- }
- }
- UnlockList(c->AccountList);
- }
- // Write the CA certificate
- void CiWriteCACert(CLIENT *c, FOLDER *f, X *x)
- {
- BUF *b;
- // Validate arguments
- if (c == NULL || f == NULL || x == NULL)
- {
- return;
- }
- b = XToBuf(x, false);
- CfgAddBuf(f, "X509", b);
- FreeBuf(b);
- }
- // Write a VLAN
- void CiWriteVLan(CLIENT *c, FOLDER *f, UNIX_VLAN *v)
- {
- char tmp[MAX_SIZE];
- // Validate arguments
- if (c == NULL || f == NULL || v == NULL)
- {
- return;
- }
- MacToStr(tmp, sizeof(tmp), v->MacAddress);
- CfgAddStr(f, "MacAddress", tmp);
- CfgAddBool(f, "Enabled", v->Enabled);
- }
- // Write a VLAN list
- void CiWriteVLanList(CLIENT *c, FOLDER *f)
- {
- // Validate arguments
- if (c == NULL || f == NULL)
- {
- return;
- }
- LockList(c->UnixVLanList);
- {
- UINT i;
- for (i = 0;i < LIST_NUM(c->UnixVLanList);i++)
- {
- UNIX_VLAN *v = LIST_DATA(c->UnixVLanList, i);
- CiWriteVLan(c, CfgCreateFolder(f, v->Name), v);
- }
- }
- UnlockList(c->UnixVLanList);
- }
- // Write the CA list
- void CiWriteCAList(CLIENT *c, FOLDER *f)
- {
- CEDAR *cedar;
- // Validate arguments
- if (c == NULL || f == NULL)
- {
- return;
- }
- cedar = c->Cedar;
- LockList(cedar->CaList);
- {
- UINT i;
- for (i = 0;i < LIST_NUM(cedar->CaList);i++)
- {
- char tmp[MAX_SIZE];
- X *x = LIST_DATA(cedar->CaList, i);
- Format(tmp, sizeof(tmp), "Certificate%u", i);
- CiWriteCACert(c, CfgCreateFolder(f, tmp), x);
- }
- }
- UnlockList(cedar->CaList);
- }
- // Write the current settings to ROOT
- void CiWriteSettingToCfg(CLIENT *c, FOLDER *root)
- {
- FOLDER *cc;
- FOLDER *account_database;
- FOLDER *ca;
- FOLDER *vlan;
- FOLDER *cmsetting;
- FOLDER *proxy;
- // Validate arguments
- if (c == NULL || root == NULL)
- {
- return;
- }
- cmsetting = CfgCreateFolder(root, "ClientManagerSetting");
- // CLIENT_CONFIG
- cc = CfgCreateFolder(root, "Config");
- CiWriteClientConfig(cc, &c->Config);
- // Eraser
- CfgAddInt64(cc, "AutoDeleteCheckDiskFreeSpaceMin", c->Eraser->MinFreeSpace);
- // Account Database
- account_database = CfgCreateFolder(root, "AccountDatabase");
- CiWriteAccountDatabase(c, account_database);
- // Proxy
- proxy = CfgCreateFolder(root, "CommonProxySetting");
- if (proxy != NULL)
- {
- INTERNET_SETTING *t = &c->CommonProxySetting;
- BUF *pw;
- CfgAddInt(proxy, "ProxyType", t->ProxyType);
- CfgAddStr(proxy, "ProxyHostName", t->ProxyHostName);
- CfgAddInt(proxy, "ProxyPort", t->ProxyPort);
- CfgAddStr(proxy, "ProxyUsername", t->ProxyUsername);
- if (IsEmptyStr(t->ProxyPassword) == false)
- {
- pw = EncryptPassword(t->ProxyPassword);
- CfgAddBuf(proxy, "ProxyPassword", pw);
- FreeBuf(pw);
- }
- }
- // CA
- ca = CfgCreateFolder(root, "RootCA");
- CiWriteCAList(c, ca);
- // VLAN
- if (OS_IS_UNIX(GetOsInfo()->OsType)
- #ifdef NO_VLAN
- && GetOsInfo()->OsType != OSTYPE_MACOS_X
- #endif // NO_VLAN
- )
- {
- vlan = CfgCreateFolder(root, "UnixVLan");
- CiWriteVLanList(c, vlan);
- }
- // Password
- CfgAddByte(root, "EncryptedPassword", c->EncryptedPassword, SHA1_SIZE);
- CfgAddBool(root, "PasswordRemoteOnly", c->PasswordRemoteOnly);
- // UseSecureDeviceId
- CfgAddInt(root, "UseSecureDeviceId", c->UseSecureDeviceId);
- // DontSavePassword
- CfgAddBool(root, "DontSavePassword", c->DontSavePassword);
- // UserAgent
- if (c->Cedar != NULL)
- {
- CfgAddStr(root, "UserAgent", c->Cedar->HttpUserAgent);
- }
- if (cmsetting != NULL)
- {
- CM_SETTING *s = c->CmSetting;
- CfgAddBool(cmsetting, "EasyMode", s->EasyMode);
- CfgAddBool(cmsetting, "LockMode", s->LockMode);
- if (IsZero(s->HashedPassword, sizeof(s->HashedPassword)) == false)
- {
- CfgAddByte(cmsetting, "HashedPassword", s->HashedPassword, sizeof(s->HashedPassword));
- }
- }
- }
- // Create the inner VPN Server
- SERVER *CiNewInnerVPNServer(CLIENT *c)
- {
- SERVER *s = NULL;
- // Validate arguments
- if (c == NULL)
- {
- return NULL;
- }
- SetNatTLowPriority();
- s = SiNewServerEx(false, true);
- return s;
- }
- // Stop the inner VPN Server
- void CiFreeInnerVPNServer(CLIENT *c, SERVER *s)
- {
- // Validate arguments
- if (c == NULL || s == NULL)
- {
- return;
- }
- SiReleaseServer(s);
- }
- // Apply settings of Inner VPN Server
- void CiApplyInnerVPNServerConfig(CLIENT *c)
- {
- }
- // Write to the configuration file
- void CiSaveConfigurationFile(CLIENT *c)
- {
- FOLDER *root;
- // Validate arguments
- if (c == NULL)
- {
- return;
- }
-
- // Do not save the configuration file
- if(c->NoSaveConfig)
- {
- return;
- }
- root = CfgCreateFolder(NULL, TAG_ROOT);
- CiWriteSettingToCfg(c, root);
- SaveCfgRw(c->CfgRw, root);
- CfgDeleteFolder(root);
- }
- // Set the CM_SETTING
- bool CtSetCmSetting(CLIENT *c, CM_SETTING *s)
- {
- // Validate arguments
- if (c == NULL || s == NULL)
- {
- return false;
- }
- Copy(c->CmSetting, s, sizeof(CM_SETTING));
- CiSaveConfigurationFile(c);
- return true;
- }
- // Get the CM_SETTING
- bool CtGetCmSetting(CLIENT *c, CM_SETTING *s)
- {
- // Validate arguments
- if (c == NULL || s == NULL)
- {
- return false;
- }
- Copy(s, c->CmSetting, sizeof(CM_SETTING));
-
- return true;
- }
- // Get the client version
- bool CtGetClientVersion(CLIENT *c, RPC_CLIENT_VERSION *ver)
- {
- // Validate arguments
- if (ver == NULL)
- {
- return false;
- }
- Zero(ver, sizeof(RPC_CLIENT_VERSION));
- StrCpy(ver->ClientProductName, sizeof(ver->ClientProductName), CEDAR_CLIENT_STR);
- StrCpy(ver->ClientVersionString, sizeof(ver->ClientVersionString), c->Cedar->VerString);
- StrCpy(ver->ClientBuildInfoString, sizeof(ver->ClientBuildInfoString), c->Cedar->BuildInfo);
- ver->ClientVerInt = c->Cedar->Version;
- ver->ClientBuildInt = c->Cedar->Build;
- #ifdef OS_WIN32
- ver->ProcessId = MsGetProcessId();
- ver->IsVLanNameRegulated = MsIsInfCatalogRequired();
- #endif // OS_WIN32
- ver->OsType = GetOsInfo()->OsType;
- return true;
- }
- // Creating a Client object
- CLIENT *CiNewClient()
- {
- CLIENT *c = ZeroMalloc(sizeof(CLIENT));
- // StartCedarLog();
- if (ci_active_sessions_lock == NULL)
- {
- ci_active_sessions_lock = NewLock();
- ci_num_active_sessions = 0;
- }
- c->CmSetting = ZeroMalloc(sizeof(CM_SETTING));
- c->SockList = NewSockList();
- c->lock = NewLock();
- c->lockForConnect = NewLock();
- c->ref = NewRef();
- c->Cedar = NewCedar(NULL, NULL);
- c->Cedar->Client = c;
- c->NotifyCancelList = NewList(NULL);
- Hash(c->EncryptedPassword, "", 0, true);
- #ifdef OS_WIN32
- c->GlobalPulse = MsOpenOrCreateGlobalPulse(CLIENT_GLOBAL_PULSE_NAME);
- #endif // OS_WIN32
- if (c->GlobalPulse != NULL)
- {
- c->PulseRecvThread = NewThread(CiPulseRecvThread, c);
- }
- CiLoadIniSettings(c);
- // Log Settings
- if(c->NoSaveLog == false)
- {
- MakeDir(CLIENT_LOG_DIR_NAME);
- c->Logger = NewLog(CLIENT_LOG_DIR_NAME, CLIENT_LOG_PREFIX, LOG_SWITCH_DAY);
- }
- CLog(c, "L_LINE");
- CLog(c, "LC_START_2", CEDAR_CLIENT_STR, c->Cedar->VerString);
- CLog(c, "LC_START_3", c->Cedar->BuildInfo);
- CLog(c, "LC_START_1");
- #ifdef OS_WIN32
- {
- // Initialize the Win32 UI
- wchar_t tmp[MAX_SIZE];
- StrToUni(tmp, sizeof(tmp), CEDAR_CLIENT_STR);
- InitWinUi(tmp, _SS("DEFAULT_FONT"), _II("DEFAULT_FONT_SIZE"));
- }
- #endif // OS_WIN32
- // Initialize the settings
- CiInitConfiguration(c);
- // Raise the priority
- OSSetHighPriority();
- #ifdef OS_WIN32
- // For Win9x, release the DHCP address of all the virtual LAN card
- if (MsIsNt() == false)
- {
- Win32ReleaseAllDhcp9x(true);
- }
- #endif // OS_WIN32
- CiChangeAllVLanMacAddressIfMachineChanged(c);
- CiChangeAllVLanMacAddressIfCleared(c);
- // Initialize the internal VPN server
- CiApplyInnerVPNServerConfig(c);
- return c;
- }
- // Examine whether two proxy server settings equal
- bool CompareInternetSetting(INTERNET_SETTING *s1, INTERNET_SETTING *s2)
- {
- // Validate arguments
- if (s1 == NULL || s2 == NULL)
- {
- return false;
- }
- if (s1->ProxyType != s2->ProxyType)
- {
- return false;
- }
- if (s1->ProxyType == PROXY_DIRECT)
- {
- return true;
- }
- if (s1->ProxyPort != s2->ProxyPort)
- {
- return false;
- }
- if (StrCmp(s1->ProxyHostName, s2->ProxyHostName) != 0)
- {
- return false;
- }
- if (StrCmp(s1->ProxyUsername, s2->ProxyUsername) != 0)
- {
- return false;
- }
- if (StrCmp(s1->ProxyPassword, s2->ProxyPassword) != 0)
- {
- return false;
- }
- return true;
- }
- // Send a global pulse
- void CiSendGlobalPulse(CLIENT *c)
- {
- // Validate arguments
- if (c == NULL)
- {
- return;
- }
- #ifdef OS_WIN32
- MsSendGlobalPulse(c->GlobalPulse);
- #endif // OS_WIN32
- }
- // Pulse reception thread
- void CiPulseRecvThread(THREAD *thread, void *param)
- {
- #ifdef OS_WIN32
- CLIENT *c = (CLIENT *)param;
- if (c == NULL)
- {
- return;
- }
- while (true)
- {
- if (c->HaltPulseThread)
- {
- break;
- }
- MsWaitForGlobalPulse(c->GlobalPulse, INFINITE);
- if (c->HaltPulseThread)
- {
- break;
- }
- CiNotifyInternal(c);
- }
- #endif // OS_WIN32
- }
- // Clean-up the client
- void CiCleanupClient(CLIENT *c)
- {
- // Validate arguments
- if (c == NULL)
- {
- return;
- }
- // Release the settings
- CiFreeConfiguration(c);
- #ifdef OS_WIN32
- // Release the Win32 UI
- FreeWinUi();
- #endif // OS_WIN32
- CLog(c, "LC_END");
- CLog(c, "L_LINE");
- FreeEraser(c->Eraser);
- FreeLog(c->Logger);
- c->Logger = NULL;
- ReleaseCedar(c->Cedar);
- DeleteLock(c->lockForConnect);
- DeleteLock(c->lock);
- c->HaltPulseThread = true;
- if (c->GlobalPulse != NULL)
- {
- #ifdef OS_WIN32
- MsSendGlobalPulse(c->GlobalPulse);
- #endif // OS_WIN32
- }
- if (c->PulseRecvThread != NULL)
- {
- WaitThread(c->PulseRecvThread, INFINITE);
- ReleaseThread(c->PulseRecvThread);
- }
- if (c->GlobalPulse != NULL)
- {
- #ifdef OS_WIN32
- MsCloseGlobalPulse(c->GlobalPulse);
- #endif // OS_WIN32
- }
- ReleaseList(c->NotifyCancelList);
- FreeSockList(c->SockList);
- Free(c->CmSetting);
- Free(c);
- #ifdef OS_WIN32
- // For Win9x, release the DHCP address of all the virtual LAN card
- if (MsIsNt() == false)
- {
- Win32ReleaseAllDhcp9x(true);
- }
- #endif // OS_WIN32
- StopCedarLog();
- if (ci_active_sessions_lock != NULL)
- {
- DeleteLock(ci_active_sessions_lock);
- ci_active_sessions_lock = NULL;
- ci_num_active_sessions = 0;
- }
- }
- // Increment of the number of active sessions
- void CiIncrementNumActiveSessions()
- {
- Lock(ci_active_sessions_lock);
- {
- ci_num_active_sessions++;
- }
- Unlock(ci_active_sessions_lock);
- }
- // Decrement of the number of active sessions
- void CiDecrementNumActiveSessions()
- {
- Lock(ci_active_sessions_lock);
- {
- if (ci_num_active_sessions >= 1)
- {
- ci_num_active_sessions--;
- }
- }
- Unlock(ci_active_sessions_lock);
- }
- // Get the number of active sessions
- UINT CiGetNumActiveSessions()
- {
- UINT ret;
- Lock(ci_active_sessions_lock);
- {
- ret = ci_num_active_sessions;
- }
- Unlock(ci_active_sessions_lock);
- return ret;
- }
- // Release the client
- void CtReleaseClient(CLIENT *c)
- {
- // Validate arguments
- if (c == NULL)
- {
- return;
- }
- if (Release(c->ref) == 0)
- {
- CiCleanupClient(c);
- }
- }
- // Start the operation of the client program
- void CtStartClient()
- {
- UINT i;
- LIST *o;
- if (client != NULL)
- {
- // It is already in running
- return;
- }
- // OS check
- CiCheckOs();
- #ifdef OS_WIN32
- RegistWindowsFirewallAll();
- #endif
- // Creating a client
- client = CiNewClient();
- // Start the Keep
- CiInitKeep(client);
- // Start the RPC server
- CiStartRpcServer(client);
- // Start the Saver
- CiInitSaver(client);
- // Start the startup connection
- o = NewListFast(NULL);
- LockList(client->AccountList);
- {
- for (i = 0;i < LIST_NUM(client->AccountList);i++)
- {
- ACCOUNT *a = LIST_DATA(client->AccountList, i);
- Lock(a->lock);
- {
- if (a->StartupAccount)
- {
- Add(o, CopyUniStr(a->ClientOption->AccountName));
- }
- }
- Unlock(a->lock);
- }
- }
- UnlockList(client->AccountList);
- for (i = 0;i < LIST_NUM(o);i++)
- {
- wchar_t *s = LIST_DATA(o, i);
- RPC_CLIENT_CONNECT c;
- Zero(&c, sizeof(c));
- UniStrCpy(c.AccountName, sizeof(c.AccountName), s);
- CtConnect(client, &c);
- Free(s);
- }
- ReleaseList(o);
- }
- // Stop the operation of the client program
- void CtStopClient()
- {
- UINT i, num;
- ACCOUNT **account_list;
- if (client == NULL)
- {
- // It is not running yet
- return;
- }
- // Halting flag
- client->Halt = true;
- // Disconnect all the RPC
- CiStopRpcServer(client);
- // Exit the client notification service
- CncExit();
- // Exit the Keep
- CiFreeKeep(client);
- // Disconnect all accounts connected
- LockList(client->AccountList);
- {
- num = LIST_NUM(client->AccountList);
- account_list = ToArray(client->AccountList);
- }
- UnlockList(client->AccountList);
- for (i = 0;i < num;i++)
- {
- ACCOUNT *a = account_list[i];
- SESSION *s = NULL;
- Lock(a->lock);
- {
- if (a->ClientSession != NULL)
- {
- s = a->ClientSession;
- AddRef(s->ref);
- }
- }
- Unlock(a->lock);
- if (s != NULL)
- {
- StopSession(s);
- ReleaseSession(s);
- Lock(a->lock);
- {
- if (a->ClientSession != NULL)
- {
- ReleaseSession(a->ClientSession);
- a->ClientSession = NULL;
- }
- }
- Unlock(a->lock);
- }
- }
- Free(account_list);
- // Stop the Saver
- CiFreeSaver(client);
- // Release the client
- CtReleaseClient(client);
- client = NULL;
- }
- // OS check
- void CiCheckOs()
- {
- // Get the OS type
- OS_INFO *info = GetOsInfo();
- if (OS_IS_WINDOWS(info->OsType))
- {
- bool ok = IS_CLIENT_SUPPORTED_OS(info->OsType);
- if (ok == false)
- {
- Alert(
- CEDAR_PRODUCT_STR " VPN Client doesn't support this Windows Operating System.\n"
- CEDAR_PRODUCT_STR " VPN Client requires Windows 98, Windows Me, Windows 2000, Windows XP, Windows Server 2003 or Greater.\n\n"
- "Please contact your system administrator.", CEDAR_PRODUCT_STR " VPN Client");
- exit(0);
- }
- }
- }
- // Get the client object
- CLIENT *CtGetClient()
- {
- if (client == NULL)
- {
- return NULL;
- }
- AddRef(client->ref);
- return client;
- }
- // Client status indicator
- void CiClientStatusPrinter(SESSION *s, wchar_t *status)
- {
- #ifdef OS_WIN32
- ACCOUNT *a;
- // Validate arguments
- if (s == NULL || status == NULL)
- {
- return;
- }
- a = s->Account;
- if (a == NULL)
- {
- return;
- }
- if (UniStrCmpi(status, L"init") == 0)
- {
- if (a->StatusWindow == NULL && s->Win32HideConnectWindow == false)
- {
- a->StatusWindow = CncStatusPrinterWindowStart(s);
- }
- }
- else if (UniStrCmpi(status, L"free") == 0)
- {
- if (a->StatusWindow != NULL)
- {
- CncStatusPrinterWindowStop(a->StatusWindow);
- a->StatusWindow = NULL;
- }
- }
- else
- {
- if (a->StatusWindow != NULL)
- {
- CncStatusPrinterWindowPrint(a->StatusWindow, status);
- }
- }
- #else // OS_WIN32
- UniPrint(L"Status: %s\n", status);
- #endif // OS_WIN32
- }
- // Developed by SoftEther VPN Project at University of Tsukuba in Japan.
- // Department of Computer Science has dozens of overly-enthusiastic geeks.
- // Join us: http://www.tsukuba.ac.jp/english/admission/
|