vlmcsdmulti_all.c 240 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910291129122913291429152916291729182919292029212922292329242925292629272928292929302931293229332934293529362937293829392940294129422943294429452946294729482949295029512952295329542955295629572958295929602961296229632964296529662967296829692970297129722973297429752976297729782979298029812982298329842985298629872988298929902991299229932994299529962997299829993000300130023003300430053006300730083009301030113012301330143015301630173018301930203021302230233024302530263027302830293030303130323033303430353036303730383039304030413042304330443045304630473048304930503051305230533054305530563057305830593060306130623063306430653066306730683069307030713072307330743075307630773078307930803081308230833084308530863087308830893090309130923093309430953096309730983099310031013102310331043105310631073108310931103111311231133114311531163117311831193120312131223123312431253126312731283129313031313132313331343135313631373138313931403141314231433144314531463147314831493150315131523153315431553156315731583159316031613162316331643165316631673168316931703171317231733174317531763177317831793180318131823183318431853186318731883189319031913192319331943195319631973198319932003201320232033204320532063207320832093210321132123213321432153216321732183219322032213222322332243225322632273228322932303231323232333234323532363237323832393240324132423243324432453246324732483249325032513252325332543255325632573258325932603261326232633264326532663267326832693270327132723273327432753276327732783279328032813282328332843285328632873288328932903291329232933294329532963297329832993300330133023303330433053306330733083309331033113312331333143315331633173318331933203321332233233324332533263327332833293330333133323333333433353336333733383339334033413342334333443345334633473348334933503351335233533354335533563357335833593360336133623363336433653366336733683369337033713372337333743375337633773378337933803381338233833384338533863387338833893390339133923393339433953396339733983399340034013402340334043405340634073408340934103411341234133414341534163417341834193420342134223423342434253426342734283429343034313432343334343435343634373438343934403441344234433444344534463447344834493450345134523453345434553456345734583459346034613462346334643465346634673468346934703471347234733474347534763477347834793480348134823483348434853486348734883489349034913492349334943495349634973498349935003501350235033504350535063507350835093510351135123513351435153516351735183519352035213522352335243525352635273528352935303531353235333534353535363537353835393540354135423543354435453546354735483549355035513552355335543555355635573558355935603561356235633564356535663567356835693570357135723573357435753576357735783579358035813582358335843585358635873588358935903591359235933594359535963597359835993600360136023603360436053606360736083609361036113612361336143615361636173618361936203621362236233624362536263627362836293630363136323633363436353636363736383639364036413642364336443645364636473648364936503651365236533654365536563657365836593660366136623663366436653666366736683669367036713672367336743675367636773678367936803681368236833684368536863687368836893690369136923693369436953696369736983699370037013702370337043705370637073708370937103711371237133714371537163717371837193720372137223723372437253726372737283729373037313732373337343735373637373738373937403741374237433744374537463747374837493750375137523753375437553756375737583759376037613762376337643765376637673768376937703771377237733774377537763777377837793780378137823783378437853786378737883789379037913792379337943795379637973798379938003801380238033804380538063807380838093810381138123813381438153816381738183819382038213822382338243825382638273828382938303831383238333834383538363837383838393840384138423843384438453846384738483849385038513852385338543855385638573858385938603861386238633864386538663867386838693870387138723873387438753876387738783879388038813882388338843885388638873888388938903891389238933894389538963897389838993900390139023903390439053906390739083909391039113912391339143915391639173918391939203921392239233924392539263927392839293930393139323933393439353936393739383939394039413942394339443945394639473948394939503951395239533954395539563957395839593960396139623963396439653966396739683969397039713972397339743975397639773978397939803981398239833984398539863987398839893990399139923993399439953996399739983999400040014002400340044005400640074008400940104011401240134014401540164017401840194020402140224023402440254026402740284029403040314032403340344035403640374038403940404041404240434044404540464047404840494050405140524053405440554056405740584059406040614062406340644065406640674068406940704071407240734074407540764077407840794080408140824083408440854086408740884089409040914092409340944095409640974098409941004101410241034104410541064107410841094110411141124113411441154116411741184119412041214122412341244125412641274128412941304131413241334134413541364137413841394140414141424143414441454146414741484149415041514152415341544155415641574158415941604161416241634164416541664167416841694170417141724173417441754176417741784179418041814182418341844185418641874188418941904191419241934194419541964197419841994200420142024203420442054206420742084209421042114212421342144215421642174218421942204221422242234224422542264227422842294230423142324233423442354236423742384239424042414242424342444245424642474248424942504251425242534254425542564257425842594260426142624263426442654266426742684269427042714272427342744275427642774278427942804281428242834284428542864287428842894290429142924293429442954296429742984299430043014302430343044305430643074308430943104311431243134314431543164317431843194320432143224323432443254326432743284329433043314332433343344335433643374338433943404341434243434344434543464347434843494350435143524353435443554356435743584359436043614362436343644365436643674368436943704371437243734374437543764377437843794380438143824383438443854386438743884389439043914392439343944395439643974398439944004401440244034404440544064407440844094410441144124413441444154416441744184419442044214422442344244425442644274428442944304431443244334434443544364437443844394440444144424443444444454446444744484449445044514452445344544455445644574458445944604461446244634464446544664467446844694470447144724473447444754476447744784479448044814482448344844485448644874488448944904491449244934494449544964497449844994500450145024503450445054506450745084509451045114512451345144515451645174518451945204521452245234524452545264527452845294530453145324533453445354536453745384539454045414542454345444545454645474548454945504551455245534554455545564557455845594560456145624563456445654566456745684569457045714572457345744575457645774578457945804581458245834584458545864587458845894590459145924593459445954596459745984599460046014602460346044605460646074608460946104611461246134614461546164617461846194620462146224623462446254626462746284629463046314632463346344635463646374638463946404641464246434644464546464647464846494650465146524653465446554656465746584659466046614662466346644665466646674668466946704671467246734674467546764677467846794680468146824683468446854686468746884689469046914692469346944695469646974698469947004701470247034704470547064707470847094710471147124713471447154716471747184719472047214722472347244725472647274728472947304731473247334734473547364737473847394740474147424743474447454746474747484749475047514752475347544755475647574758475947604761476247634764476547664767476847694770477147724773477447754776477747784779478047814782478347844785478647874788478947904791479247934794479547964797479847994800480148024803480448054806480748084809481048114812481348144815481648174818481948204821482248234824482548264827482848294830483148324833483448354836483748384839484048414842484348444845484648474848484948504851485248534854485548564857485848594860486148624863486448654866486748684869487048714872487348744875487648774878487948804881488248834884488548864887488848894890489148924893489448954896489748984899490049014902490349044905490649074908490949104911491249134914491549164917491849194920492149224923492449254926492749284929493049314932493349344935493649374938493949404941494249434944494549464947494849494950495149524953495449554956495749584959496049614962496349644965496649674968496949704971497249734974497549764977497849794980498149824983498449854986498749884989499049914992499349944995499649974998499950005001500250035004500550065007500850095010501150125013501450155016501750185019502050215022502350245025502650275028502950305031503250335034503550365037503850395040504150425043504450455046504750485049505050515052505350545055505650575058505950605061506250635064506550665067506850695070507150725073507450755076507750785079508050815082508350845085508650875088508950905091509250935094509550965097509850995100510151025103510451055106510751085109511051115112511351145115511651175118511951205121512251235124512551265127512851295130513151325133513451355136513751385139514051415142514351445145514651475148514951505151515251535154515551565157515851595160516151625163516451655166516751685169517051715172517351745175517651775178517951805181518251835184518551865187518851895190519151925193519451955196519751985199520052015202520352045205520652075208520952105211521252135214521552165217521852195220522152225223522452255226522752285229523052315232523352345235523652375238523952405241524252435244524552465247524852495250525152525253525452555256525752585259526052615262526352645265526652675268526952705271527252735274527552765277527852795280528152825283528452855286528752885289529052915292529352945295529652975298529953005301530253035304530553065307530853095310531153125313531453155316531753185319532053215322532353245325532653275328532953305331533253335334533553365337533853395340534153425343534453455346534753485349535053515352535353545355535653575358535953605361536253635364536553665367536853695370537153725373537453755376537753785379538053815382538353845385538653875388538953905391539253935394539553965397539853995400540154025403540454055406540754085409541054115412541354145415541654175418541954205421542254235424542554265427542854295430543154325433543454355436543754385439544054415442544354445445544654475448544954505451545254535454545554565457545854595460546154625463546454655466546754685469547054715472547354745475547654775478547954805481548254835484548554865487548854895490549154925493549454955496549754985499550055015502550355045505550655075508550955105511551255135514551555165517551855195520552155225523552455255526552755285529553055315532553355345535553655375538553955405541554255435544554555465547554855495550555155525553555455555556555755585559556055615562556355645565556655675568556955705571557255735574557555765577557855795580558155825583558455855586558755885589559055915592559355945595559655975598559956005601560256035604560556065607560856095610561156125613561456155616561756185619562056215622562356245625562656275628562956305631563256335634563556365637563856395640564156425643564456455646564756485649565056515652565356545655565656575658565956605661566256635664566556665667566856695670567156725673567456755676567756785679568056815682568356845685568656875688568956905691569256935694569556965697569856995700570157025703570457055706570757085709571057115712571357145715571657175718571957205721572257235724572557265727572857295730573157325733573457355736573757385739574057415742574357445745574657475748574957505751575257535754575557565757575857595760576157625763576457655766576757685769577057715772577357745775577657775778577957805781578257835784578557865787578857895790579157925793579457955796579757985799580058015802580358045805580658075808580958105811581258135814581558165817581858195820582158225823582458255826582758285829583058315832583358345835583658375838583958405841584258435844584558465847584858495850585158525853585458555856585758585859586058615862586358645865586658675868586958705871587258735874587558765877587858795880588158825883588458855886588758885889589058915892589358945895589658975898589959005901590259035904590559065907590859095910591159125913591459155916591759185919592059215922592359245925592659275928592959305931593259335934593559365937593859395940594159425943594459455946594759485949595059515952595359545955595659575958595959605961596259635964596559665967596859695970597159725973597459755976597759785979598059815982598359845985598659875988598959905991599259935994599559965997599859996000600160026003600460056006600760086009601060116012601360146015601660176018601960206021602260236024602560266027602860296030603160326033603460356036603760386039604060416042604360446045604660476048604960506051605260536054605560566057605860596060606160626063606460656066606760686069607060716072607360746075607660776078607960806081608260836084608560866087608860896090609160926093609460956096609760986099610061016102610361046105610661076108610961106111611261136114611561166117611861196120612161226123612461256126612761286129613061316132613361346135613661376138613961406141614261436144614561466147614861496150615161526153615461556156615761586159616061616162616361646165616661676168616961706171617261736174617561766177617861796180618161826183618461856186618761886189619061916192619361946195619661976198619962006201620262036204620562066207620862096210621162126213621462156216621762186219622062216222622362246225622662276228622962306231623262336234623562366237623862396240624162426243624462456246624762486249625062516252625362546255625662576258625962606261626262636264626562666267626862696270627162726273627462756276627762786279628062816282628362846285628662876288628962906291629262936294629562966297629862996300630163026303630463056306630763086309631063116312631363146315631663176318631963206321632263236324632563266327632863296330633163326333633463356336633763386339634063416342634363446345634663476348634963506351635263536354635563566357635863596360636163626363636463656366636763686369637063716372637363746375637663776378637963806381638263836384638563866387638863896390639163926393639463956396639763986399640064016402640364046405640664076408640964106411641264136414641564166417641864196420642164226423642464256426642764286429643064316432643364346435643664376438643964406441644264436444644564466447644864496450645164526453645464556456645764586459646064616462646364646465646664676468646964706471647264736474647564766477647864796480648164826483648464856486648764886489649064916492649364946495649664976498649965006501650265036504650565066507650865096510651165126513651465156516651765186519652065216522652365246525652665276528652965306531653265336534653565366537653865396540654165426543654465456546654765486549655065516552655365546555655665576558655965606561656265636564656565666567656865696570657165726573657465756576657765786579658065816582658365846585658665876588658965906591659265936594659565966597659865996600660166026603660466056606660766086609661066116612661366146615661666176618661966206621662266236624662566266627662866296630663166326633663466356636663766386639664066416642664366446645664666476648664966506651665266536654665566566657665866596660666166626663666466656666666766686669667066716672667366746675667666776678667966806681668266836684668566866687668866896690669166926693669466956696669766986699670067016702670367046705670667076708670967106711671267136714671567166717671867196720672167226723672467256726672767286729673067316732673367346735673667376738673967406741674267436744674567466747674867496750675167526753675467556756675767586759676067616762676367646765676667676768676967706771677267736774677567766777677867796780678167826783678467856786678767886789679067916792679367946795679667976798679968006801680268036804680568066807680868096810681168126813681468156816681768186819682068216822682368246825682668276828682968306831683268336834683568366837683868396840684168426843684468456846684768486849685068516852685368546855685668576858685968606861686268636864686568666867686868696870687168726873687468756876687768786879688068816882688368846885688668876888688968906891689268936894689568966897689868996900690169026903690469056906690769086909691069116912691369146915691669176918691969206921692269236924692569266927692869296930693169326933693469356936693769386939694069416942694369446945694669476948694969506951695269536954695569566957695869596960696169626963696469656966696769686969697069716972697369746975697669776978697969806981698269836984698569866987698869896990699169926993699469956996699769986999700070017002700370047005700670077008700970107011701270137014701570167017701870197020702170227023702470257026702770287029703070317032703370347035703670377038703970407041704270437044704570467047704870497050705170527053705470557056705770587059706070617062706370647065706670677068706970707071707270737074707570767077707870797080708170827083708470857086708770887089709070917092709370947095709670977098709971007101710271037104710571067107710871097110711171127113711471157116711771187119712071217122712371247125712671277128712971307131713271337134713571367137713871397140714171427143714471457146714771487149715071517152715371547155715671577158715971607161716271637164716571667167716871697170717171727173717471757176717771787179718071817182718371847185718671877188718971907191719271937194719571967197719871997200720172027203720472057206720772087209721072117212721372147215721672177218721972207221722272237224722572267227722872297230723172327233723472357236723772387239724072417242724372447245724672477248724972507251725272537254725572567257725872597260726172627263726472657266726772687269727072717272727372747275727672777278727972807281728272837284728572867287728872897290729172927293729472957296729772987299730073017302730373047305730673077308730973107311731273137314731573167317731873197320732173227323732473257326732773287329733073317332733373347335733673377338733973407341734273437344734573467347734873497350735173527353735473557356735773587359736073617362736373647365736673677368736973707371737273737374737573767377737873797380738173827383738473857386738773887389739073917392739373947395739673977398739974007401740274037404740574067407740874097410741174127413741474157416741774187419742074217422742374247425742674277428742974307431743274337434743574367437743874397440744174427443744474457446744774487449745074517452745374547455745674577458745974607461746274637464746574667467746874697470747174727473747474757476747774787479748074817482748374847485748674877488748974907491749274937494749574967497749874997500750175027503750475057506750775087509751075117512751375147515751675177518751975207521752275237524752575267527752875297530753175327533753475357536753775387539754075417542754375447545754675477548754975507551755275537554755575567557755875597560756175627563756475657566756775687569757075717572757375747575757675777578757975807581758275837584758575867587758875897590759175927593759475957596759775987599760076017602760376047605760676077608760976107611761276137614761576167617761876197620762176227623762476257626762776287629763076317632763376347635763676377638763976407641764276437644764576467647764876497650765176527653765476557656765776587659766076617662766376647665766676677668766976707671767276737674767576767677767876797680768176827683768476857686768776887689769076917692769376947695769676977698769977007701770277037704770577067707770877097710771177127713771477157716771777187719772077217722772377247725772677277728772977307731773277337734773577367737773877397740774177427743774477457746774777487749775077517752775377547755775677577758775977607761776277637764776577667767776877697770777177727773777477757776777777787779778077817782778377847785778677877788778977907791779277937794779577967797779877997800780178027803780478057806780778087809781078117812781378147815781678177818781978207821782278237824782578267827782878297830783178327833783478357836783778387839784078417842784378447845784678477848784978507851785278537854785578567857785878597860786178627863786478657866786778687869787078717872787378747875787678777878787978807881788278837884788578867887788878897890789178927893789478957896789778987899790079017902790379047905790679077908790979107911791279137914791579167917791879197920792179227923792479257926792779287929793079317932793379347935793679377938793979407941794279437944794579467947794879497950795179527953795479557956795779587959796079617962796379647965796679677968796979707971797279737974797579767977797879797980798179827983798479857986798779887989799079917992799379947995799679977998799980008001800280038004800580068007800880098010801180128013801480158016801780188019802080218022802380248025802680278028802980308031803280338034803580368037803880398040804180428043804480458046804780488049805080518052805380548055805680578058805980608061806280638064806580668067806880698070807180728073807480758076807780788079808080818082808380848085808680878088808980908091809280938094809580968097809880998100810181028103810481058106810781088109811081118112811381148115811681178118811981208121812281238124812581268127812881298130813181328133813481358136813781388139814081418142814381448145814681478148814981508151815281538154815581568157815881598160816181628163816481658166816781688169817081718172817381748175817681778178817981808181818281838184818581868187818881898190819181928193819481958196819781988199820082018202820382048205820682078208820982108211821282138214821582168217821882198220822182228223822482258226822782288229823082318232823382348235823682378238823982408241824282438244824582468247824882498250825182528253825482558256825782588259826082618262826382648265826682678268826982708271827282738274
  1. #ifndef CONFIG
  2. #define CONFIG "config.h"
  3. #endif // CONFIG
  4. #include CONFIG
  5. #if defined(USE_MSRPC) && !defined(_WIN32) && !defined(__CYGWIN__)
  6. #error Microsoft RPC is only available on Windows and Cygwin
  7. #endif
  8. #if defined(NO_SOCKETS) && defined(USE_MSRPC)
  9. #error Cannot use inetd mode with Microsoft RPC
  10. #endif
  11. #ifndef _GNU_SOURCE
  12. #define _GNU_SOURCE
  13. #endif
  14. #include <stdio.h>
  15. #include <stdlib.h>
  16. #include <string.h>
  17. #include <errno.h>
  18. #include <stdint.h>
  19. #ifndef _WIN32
  20. #include <pwd.h>
  21. #include <grp.h>
  22. #include <sys/types.h>
  23. #if !defined(NO_LIMIT) && !__minix__
  24. #include <sys/ipc.h>
  25. #if !__ANDROID__
  26. #include <sys/shm.h>
  27. #else // __ANDROID__
  28. #include <sys/syscall.h>
  29. #endif // __ANDROID__
  30. #endif // !defined(NO_LIMIT) && !__minix__
  31. #include <sys/wait.h>
  32. #include <unistd.h>
  33. #include <fcntl.h>
  34. #include <sys/stat.h>
  35. #include <semaphore.h>
  36. #endif // !_WIN32
  37. #if __APPLE__
  38. #include <mach-o/dyld.h>
  39. #endif // __APPLE__
  40. #if __linux__ && defined(USE_AUXV)
  41. #include <sys/auxv.h>
  42. #endif
  43. #if __FreeBSD__
  44. #include <sys/sysctl.h>
  45. #endif
  46. #include "vlmcsd.h"
  47. #include "endian.h"
  48. #include "shared_globals.h"
  49. #include "output.h"
  50. #ifndef USE_MSRPC
  51. #include "network.h"
  52. #else // USE_MSRPC
  53. #include "msrpc-server.h"
  54. #endif // USE_MSRPC
  55. #include "ntservice.h"
  56. #include "helpers.h"
  57. static const char* const optstring = "N:B:m:t:w:0:3:H:A:R:u:g:L:p:i:P:l:r:U:W:C:SsfeDd46VvIdqkZ";
  58. #if !defined(NO_SOCKETS)
  59. #if !defined(USE_MSRPC)
  60. static uint_fast8_t maxsockets = 0;
  61. static int_fast8_t haveIPv6Stack = 0;
  62. static int_fast8_t haveIPv4Stack = 0;
  63. static int_fast8_t v6required = 0;
  64. static int_fast8_t v4required = 0;
  65. #endif // !defined(USE_MSRPC)
  66. #endif // !defined(NO_SOCKETS)
  67. #ifdef _NTSERVICE
  68. static int_fast8_t installService = 0;
  69. static const char *restrict ServiceUser = NULL;
  70. static const char *restrict ServicePassword = "";
  71. #endif
  72. #ifndef NO_PID_FILE
  73. static const char *fn_pid = NULL;
  74. #endif
  75. #ifndef NO_INI_FILE
  76. #ifdef INI_FILE
  77. static const char *fn_ini = INI_FILE;
  78. #else // !INI_FILE
  79. static const char *fn_ini = NULL;
  80. #endif // !INI_FILE
  81. static const char* IniFileErrorMessage = "";
  82. char* IniFileErrorBuffer = NULL;
  83. #define INIFILE_ERROR_BUFFERSIZE 256
  84. static IniFileParameter_t IniFileParameterList[] =
  85. {
  86. # ifndef NO_RANDOM_EPID
  87. { "RandomizationLevel", INI_PARAM_RANDOMIZATION_LEVEL },
  88. { "LCID", INI_PARAM_LCID },
  89. # endif // NO_RANDOM_EPID
  90. # ifdef USE_MSRPC
  91. { "Port", INI_PARAM_PORT },
  92. # endif // USE_MSRPC
  93. # if !defined(NO_SOCKETS) && !defined(USE_MSRPC)
  94. { "Listen", INI_PARAM_LISTEN },
  95. # if !defined(NO_LIMIT) && !__minix__
  96. { "MaxWorkers", INI_PARAM_MAX_WORKERS },
  97. # endif // !defined(NO_LIMIT) && !__minix__
  98. # endif // !defined(NO_SOCKETS) && !defined(USE_MSRPC)
  99. # if !defined(NO_TIMEOUT) && !__minix__ && !defined(USE_MSRPC) & !defined(USE_MSRPC)
  100. { "ConnectionTimeout", INI_PARAM_CONNECTION_TIMEOUT },
  101. # endif // !defined(NO_TIMEOUT) && !__minix__ && !defined(USE_MSRPC) & !defined(USE_MSRPC)
  102. # ifndef USE_MSRPC
  103. { "DisconnectClientsImmediately", INI_PARAM_DISCONNECT_IMMEDIATELY },
  104. { "UseNDR64", INI_PARAM_RPC_NDR64 },
  105. { "UseBTFN", INI_PARAM_RPC_BTFN },
  106. # endif // USE_MSRPC
  107. # ifndef NO_PID_FILE
  108. { "PIDFile", INI_PARAM_PID_FILE },
  109. # endif // NO_PID_FILE
  110. # ifndef NO_LOG
  111. { "LogFile", INI_PARAM_LOG_FILE },
  112. # ifndef NO_VERBOSE_LOG
  113. { "LogVerbose", INI_PARAM_LOG_VERBOSE },
  114. # endif // NO_VERBOSE_LOG
  115. # endif // NO_LOG
  116. # ifndef NO_CUSTOM_INTERVALS
  117. {"ActivationInterval", INI_PARAM_ACTIVATION_INTERVAL },
  118. {"RenewalInterval", INI_PARAM_RENEWAL_INTERVAL },
  119. # endif // NO_CUSTOM_INTERVALS
  120. # if !defined(NO_USER_SWITCH) && !defined(_WIN32)
  121. { "user", INI_PARAM_UID },
  122. { "group", INI_PARAM_GID},
  123. # endif // !defined(NO_USER_SWITCH) && !defined(_WIN32)
  124. };
  125. #endif // NO_INI_FILE
  126. #if !defined(NO_LIMIT) && !defined (NO_SOCKETS) && !__minix__
  127. #if !defined(USE_THREADS) && !defined(CYGWIN) && !defined(USE_MSRPC)
  128. static int shmid = -1;
  129. #endif
  130. #if __ANDROID__ && !defined(USE_THREADS) // Bionic does not wrap these syscalls (willingly because Google fears, developers don't know how to use it)
  131. #ifdef __NR_shmget
  132. static int shmget(key_t key, size_t size, int shmflg)
  133. {
  134. return syscall(__NR_shmget, key, size, shmflg);
  135. }
  136. #endif // __NR_shmget
  137. #ifdef __NR_shmat
  138. static void *shmat(int shmid, const void *shmaddr, int shmflg)
  139. {
  140. return (void *)syscall(__NR_shmat, shmid, shmaddr, shmflg);
  141. }
  142. #endif // __NR_shmat
  143. #ifdef __NR_shmdt
  144. static int shmdt(const void *shmaddr)
  145. {
  146. return syscall(__NR_shmdt, shmaddr);
  147. }
  148. #endif // __NR_shmdt
  149. #ifdef __NR_shmctl
  150. static int shmctl(int shmid, int cmd, /*struct shmid_ds*/void *buf)
  151. {
  152. return syscall(__NR_shmctl, shmid, cmd, buf);
  153. }
  154. #endif // __NR_shmctl
  155. #endif // __ANDROID__ && !defined(USE_THREADS)
  156. #endif // !defined(NO_LIMIT) && !defined (NO_SOCKETS) && !__minix__
  157. #ifndef NO_USER_SWITCH
  158. #ifndef _WIN32
  159. static const char *uname = NULL, *gname = NULL;
  160. static gid_t gid = INVALID_GID;
  161. static uid_t uid = INVALID_UID;
  162. // Get Numeric id of user/group
  163. static char GetNumericId(gid_t *restrict id, const char *const c)
  164. {
  165. char* endptr;
  166. gid_t temp;
  167. temp = (gid_t)strtoll(c, &endptr, 10);
  168. if (!*endptr) *id = temp;
  169. return *endptr;
  170. }
  171. // Get group id from option argument
  172. static char GetGid()
  173. {
  174. struct group *g;
  175. if ((g = getgrnam(optarg)))
  176. gid = g->gr_gid;
  177. else
  178. return GetNumericId(&gid, optarg);
  179. return 0;
  180. }
  181. // Get user id from option argument
  182. static char GetUid()
  183. {
  184. struct passwd *u;
  185. ////PORTABILITY: Assumes uid_t and gid_t are of same size (shouldn't be a problem)
  186. if ((u = getpwnam(optarg)))
  187. uid = u->pw_uid;
  188. else
  189. return GetNumericId((gid_t*)&uid, optarg);
  190. return 0;
  191. }
  192. #endif // _WIN32
  193. #endif //NO_USER_SWITCH
  194. #ifdef NO_HELP
  195. static __noreturn void usage()
  196. {
  197. printerrorf("Incorrect parameters\n\n");
  198. exit(!0);
  199. }
  200. #else // HELP
  201. static __noreturn void usage()
  202. {
  203. printerrorf("vlmcsd %s\n"
  204. "\nUsage:\n"
  205. " %s [ options ]\n\n"
  206. "Where:\n"
  207. #ifndef NO_CL_PIDS
  208. " -w <ePID> always use <ePID> for Windows\n"
  209. " -0 <ePID> always use <ePID> for Office2010\n"
  210. " -3 <ePID> always use <ePID> for Office2013\n"
  211. " -H <HwId> always use hardware Id <HwId>\n"
  212. #endif // NO_CL_PIDS
  213. #if !defined(_WIN32) && !defined(NO_USER_SWITCH)
  214. " -u <user> set uid to <user>\n"
  215. " -g <group> set gid to <group>\n"
  216. #endif // !defined(_WIN32) && !defined(NO_USER_SWITCH)
  217. #ifndef NO_RANDOM_EPID
  218. " -r 0|1|2\t\tset ePID randomization level (default 1)\n"
  219. " -C <LCID>\t\tuse fixed <LCID> in random ePIDs\n"
  220. #endif // NO_RANDOM_EPID
  221. #ifndef NO_SOCKETS
  222. #ifndef USE_MSRPC
  223. " -4\t\t\tuse IPv4\n"
  224. " -6\t\t\tuse IPv6\n"
  225. " -L <address>[:<port>]\tlisten on IP address <address> with optional <port>\n"
  226. " -P <port>\t\tset TCP port <port> for subsequent -L statements (default 1688)\n"
  227. #else // USE_MSRPC
  228. " -P <port>\t\tuse TCP port <port> (default 1688)\n"
  229. #endif // USE_MSRPC
  230. #if !defined(NO_LIMIT) && !__minix__
  231. " -m <clients>\t\tHandle max. <clients> simultaneously (default no limit)\n"
  232. #endif // !defined(NO_LIMIT) && !__minix__
  233. #ifdef _NTSERVICE
  234. " -s install vlmcsd as an NT service. Ignores -e"
  235. #ifndef _WIN32
  236. ", -f and -D"
  237. #endif // _WIN32
  238. "\n"
  239. " -S remove vlmcsd service. Ignores all other options\n"
  240. " -U <username> run NT service as <username>. Must be used with -s\n"
  241. " -W <password> optional <password> for -U. Must be used with -s\n"
  242. #endif // _NTSERVICE
  243. #ifndef NO_LOG
  244. " -e log to stdout\n"
  245. #endif // NO_LOG
  246. #ifndef _WIN32 //
  247. " -D run in foreground\n"
  248. " -f run in foreground"
  249. #ifndef NO_LOG
  250. " and log to stdout"
  251. #endif // NO_LOG
  252. "\n"
  253. #endif // _WIN32
  254. #endif // NO_SOCKETS
  255. #ifndef USE_MSRPC
  256. #if !defined(NO_TIMEOUT) && !__minix__
  257. " -t <seconds>\t\tdisconnect clients after <seconds> of inactivity (default 30)\n"
  258. #endif // !defined(NO_TIMEOUT) && !__minix__
  259. " -d\t\t\tdisconnect clients after each request\n"
  260. " -k\t\t\tdon't disconnect clients after each request (default)\n"
  261. " -N0, -N1\t\tdisable/enable NDR64\n"
  262. " -B0, -B1\t\tdisable/enable bind time feature negotiation\n"
  263. #endif // USE_MSRPC
  264. #ifndef NO_PID_FILE
  265. " -p <file> write pid to <file>\n"
  266. #endif // NO_PID_FILE
  267. #ifndef NO_INI_FILE
  268. " -i <file>\t\tuse config file <file>\n"
  269. #endif // NO_INI_FILE
  270. #ifndef NO_CUSTOM_INTERVALS
  271. " -R <interval> renew activation every <interval> (default 1w)\n"
  272. " -A <interval> retry activation every <interval> (default 2h)\n"
  273. #endif // NO_CUSTOM_INTERVALS
  274. #ifndef NO_LOG
  275. #ifndef _WIN32
  276. " -l syslog log to syslog\n"
  277. #endif // _WIN32
  278. " -l <file> log to <file>\n"
  279. #ifndef NO_VERBOSE_LOG
  280. " -v\t\t\tlog verbose\n"
  281. " -q\t\t\tdon't log verbose (default)\n"
  282. #endif // NO_VERBOSE_LOG
  283. #endif // NO_LOG
  284. " -V display version information and exit"
  285. "\n",
  286. Version, global_argv[0]);
  287. exit(!0);
  288. }
  289. #endif // HELP
  290. #ifndef NO_CUSTOM_INTERVALS
  291. // Convert time span strings (e.g. "2h", "5w") to minutes
  292. __pure static DWORD timeSpanString2Minutes(const char *const restrict argument)
  293. {
  294. char *unitId;
  295. long long val = strtoll(argument, &unitId, 10);
  296. switch(toupper((int)*unitId))
  297. {
  298. case 0:
  299. case 'M':
  300. break;
  301. case 'H':
  302. val *= 60;
  303. break;
  304. case 'D':
  305. val *= 60 * 24;
  306. break;
  307. case 'W':
  308. val *= 60 * 24 * 7;
  309. break;
  310. case 'S':
  311. val /= 60;
  312. break;
  313. default:
  314. return 0;
  315. }
  316. if (val < 1) val = 1;
  317. if (val > UINT_MAX) val = UINT_MAX;
  318. return (DWORD)val;
  319. }
  320. #ifndef NO_INI_FILE
  321. __pure static BOOL getTimeSpanFromIniFile(DWORD* result, const char *const restrict argument)
  322. {
  323. DWORD val = timeSpanString2Minutes(argument);
  324. if (!val)
  325. {
  326. IniFileErrorMessage = "Incorrect time span.";
  327. return FALSE;
  328. }
  329. *result = val;
  330. return TRUE;
  331. }
  332. #endif // NO_INI_FILE
  333. __pure static DWORD getTimeSpanFromCommandLine(const char *const restrict optarg, const char optchar)
  334. {
  335. long long val = timeSpanString2Minutes(optarg);
  336. if (!val)
  337. {
  338. printerrorf("Fatal: No valid time span specified in option -%c.\n", optchar);
  339. exit (!0);
  340. }
  341. return (DWORD)val;
  342. }
  343. #endif // NO_CUSTOM_INTERVALS
  344. #ifndef NO_INI_FILE
  345. static void ignoreIniFileParameter(uint_fast8_t iniFileParameterId)
  346. {
  347. uint_fast8_t i;
  348. for (i = 0; i < _countof(IniFileParameterList); i++)
  349. {
  350. if (IniFileParameterList[i].Id != iniFileParameterId) continue;
  351. IniFileParameterList[i].Id = 0;
  352. break;
  353. }
  354. }
  355. #else // NO_INI_FILE
  356. #define ignoreIniFileParameter(x)
  357. #endif // NO_INI_FILE
  358. #ifndef NO_INI_FILE
  359. static BOOL getIniFileArgumentBool(int_fast8_t *result, const char *const argument)
  360. {
  361. IniFileErrorMessage = "Argument must be true/on/yes/1 or false/off/no/0";
  362. return getArgumentBool(result, argument);
  363. }
  364. static BOOL getIniFileArgumentInt(unsigned int *result, const char *const argument, const unsigned int min, const unsigned int max)
  365. {
  366. unsigned int tempResult;
  367. if (!stringToInt(argument, min, max, &tempResult))
  368. {
  369. snprintf(IniFileErrorBuffer, INIFILE_ERROR_BUFFERSIZE, "Must be integer between %u and %u", min, max);
  370. IniFileErrorMessage = IniFileErrorBuffer;
  371. return FALSE;
  372. }
  373. *result = tempResult;
  374. return TRUE;
  375. }
  376. static char* allocateStringArgument(const char *const argument)
  377. {
  378. char* result = (char*)vlmcsd_malloc(strlen(argument) + 1);
  379. strcpy(result, argument);
  380. return result;
  381. }
  382. static BOOL setIniFileParameter(uint_fast8_t id, const char *const iniarg)
  383. {
  384. unsigned int result;
  385. BOOL success = TRUE;
  386. switch(id)
  387. {
  388. # if !defined(NO_USER_SWITCH) && !defined(_WIN32)
  389. case INI_PARAM_GID:
  390. {
  391. struct group *g;
  392. IniFileErrorMessage = "Invalid group id or name";
  393. if (!(gname = allocateStringArgument(iniarg))) return FALSE;
  394. if ((g = getgrnam(iniarg)))
  395. gid = g->gr_gid;
  396. else
  397. success = !GetNumericId(&gid, iniarg);
  398. break;
  399. }
  400. case INI_PARAM_UID:
  401. {
  402. struct passwd *p;
  403. IniFileErrorMessage = "Invalid user id or name";
  404. if (!(uname = allocateStringArgument(iniarg))) return FALSE;
  405. if ((p = getpwnam(iniarg)))
  406. uid = p->pw_uid;
  407. else
  408. success = !GetNumericId(&uid, iniarg);
  409. break;
  410. }
  411. # endif // !defined(NO_USER_SWITCH) && !defined(_WIN32)
  412. # ifndef NO_RANDOM_EPID
  413. case INI_PARAM_LCID:
  414. success = getIniFileArgumentInt(&result, iniarg, 0, 32767);
  415. if (success) Lcid = (uint16_t)result;
  416. break;
  417. case INI_PARAM_RANDOMIZATION_LEVEL:
  418. success = getIniFileArgumentInt(&result, iniarg, 0, 2);
  419. if (success) RandomizationLevel = (int_fast8_t)result;
  420. break;
  421. # endif // NO_RANDOM_EPID
  422. # ifdef USE_MSRPC
  423. case INI_PARAM_PORT:
  424. defaultport = allocateStringArgument(iniarg);
  425. break;
  426. # endif // USE_MSRPC
  427. # if !defined(NO_SOCKETS) && !defined(USE_MSRPC)
  428. case INI_PARAM_LISTEN:
  429. maxsockets++;
  430. return TRUE;
  431. # if !defined(NO_LIMIT) && !__minix__
  432. case INI_PARAM_MAX_WORKERS:
  433. # ifdef USE_MSRPC
  434. success = getIniFileArgumentInt(&MaxTasks, iniarg, 1, RPC_C_LISTEN_MAX_CALLS_DEFAULT);
  435. # else // !USE_MSRPC
  436. success = getIniFileArgumentInt(&MaxTasks, iniarg, 1, SEM_VALUE_MAX);
  437. # endif // !USE_MSRPC
  438. break;
  439. # endif // !defined(NO_LIMIT) && !__minix__
  440. # endif // NO_SOCKETS
  441. # ifndef NO_PID_FILE
  442. case INI_PARAM_PID_FILE:
  443. fn_pid = allocateStringArgument(iniarg);
  444. break;
  445. # endif // NO_PID_FILE
  446. # ifndef NO_LOG
  447. case INI_PARAM_LOG_FILE:
  448. fn_log = allocateStringArgument(iniarg);
  449. break;
  450. # ifndef NO_VERBOSE_LOG
  451. case INI_PARAM_LOG_VERBOSE:
  452. success = getIniFileArgumentBool(&logverbose, iniarg);
  453. break;
  454. # endif // NO_VERBOSE_LOG
  455. # endif // NO_LOG
  456. # ifndef NO_CUSTOM_INTERVALS
  457. case INI_PARAM_ACTIVATION_INTERVAL:
  458. success = getTimeSpanFromIniFile(&VLActivationInterval, iniarg);
  459. break;
  460. case INI_PARAM_RENEWAL_INTERVAL:
  461. success = getTimeSpanFromIniFile(&VLRenewalInterval, iniarg);
  462. break;
  463. # endif // NO_CUSTOM_INTERVALS
  464. # ifndef USE_MSRPC
  465. # if !defined(NO_TIMEOUT) && !__minix__
  466. case INI_PARAM_CONNECTION_TIMEOUT:
  467. success = getIniFileArgumentInt(&result, iniarg, 1, 600);
  468. if (success) ServerTimeout = (DWORD)result;
  469. break;
  470. # endif // !defined(NO_TIMEOUT) && !__minix__
  471. case INI_PARAM_DISCONNECT_IMMEDIATELY:
  472. success = getIniFileArgumentBool(&DisconnectImmediately, iniarg);
  473. break;
  474. case INI_PARAM_RPC_NDR64:
  475. success = getIniFileArgumentBool(&UseRpcNDR64, iniarg);
  476. break;
  477. case INI_PARAM_RPC_BTFN:
  478. success = getIniFileArgumentBool(&UseRpcBTFN, iniarg);
  479. break;
  480. # endif // USE_MSRPC
  481. default:
  482. return FALSE;
  483. }
  484. return success;
  485. }
  486. static __pure int isControlCharOrSlash(const char c)
  487. {
  488. if ((unsigned char)c < '!') return !0;
  489. if (c == '/') return !0;
  490. return 0;
  491. }
  492. static void iniFileLineNextWord(const char **s)
  493. {
  494. while ( **s && isspace((int)**s) ) (*s)++;
  495. }
  496. static BOOL setHwIdFromIniFileLine(const char **s, const ProdListIndex_t index)
  497. {
  498. iniFileLineNextWord(s);
  499. if (**s == '/')
  500. {
  501. if (KmsResponseParameters[index].HwId) return TRUE;
  502. BYTE* HwId = (BYTE*)vlmcsd_malloc(sizeof(((RESPONSE_V6 *)0)->HwId));
  503. hex2bin(HwId, *s + 1, sizeof(((RESPONSE_V6 *)0)->HwId));
  504. KmsResponseParameters[index].HwId = HwId;
  505. }
  506. return TRUE;
  507. }
  508. static BOOL checkGuidInIniFileLine(const char **s, ProdListIndex_t *const index)
  509. {
  510. GUID AppGuid;
  511. if (!string2Uuid(*s, &AppGuid)) return FALSE;
  512. (*s) += GUID_STRING_LENGTH;
  513. getProductNameHE(&AppGuid, AppList, index);
  514. if (*index > getAppListSize() - 2)
  515. {
  516. IniFileErrorMessage = "Unknown App Guid.";
  517. return FALSE;
  518. }
  519. iniFileLineNextWord(s);
  520. if ( *(*s)++ != '=' ) return FALSE;
  521. return TRUE;
  522. }
  523. static BOOL setEpidFromIniFileLine(const char **s, const ProdListIndex_t index)
  524. {
  525. iniFileLineNextWord(s);
  526. const char *savedPosition = *s;
  527. uint_fast16_t i;
  528. for (i = 0; !isControlCharOrSlash(**s); i++)
  529. {
  530. if (utf8_to_ucs2_char((const unsigned char*)*s, (const unsigned char**)s) == (WCHAR)~0)
  531. {
  532. return FALSE;
  533. }
  534. }
  535. if (i < 1 || i >= PID_BUFFER_SIZE) return FALSE;
  536. if (KmsResponseParameters[index].Epid) return TRUE;
  537. size_t size = *s - savedPosition + 1;
  538. char* epidbuffer = (char*)vlmcsd_malloc(size);
  539. memcpy(epidbuffer, savedPosition, size - 1);
  540. epidbuffer[size - 1] = 0;
  541. KmsResponseParameters[index].Epid = epidbuffer;
  542. #ifndef NO_LOG
  543. KmsResponseParameters[index].EpidSource = fn_ini;
  544. #endif //NO_LOG
  545. return TRUE;
  546. }
  547. static BOOL getIniFileArgument(const char **s)
  548. {
  549. while (!isspace((int)**s) && **s != '=' && **s) (*s)++;
  550. iniFileLineNextWord(s);
  551. if (*((*s)++) != '=')
  552. {
  553. IniFileErrorMessage = "'=' required after keyword.";
  554. return FALSE;
  555. }
  556. iniFileLineNextWord(s);
  557. if (!**s)
  558. {
  559. IniFileErrorMessage = "missing argument after '='.";
  560. return FALSE;
  561. }
  562. return TRUE;
  563. }
  564. static BOOL handleIniFileParameter(const char *s)
  565. {
  566. uint_fast8_t i;
  567. for (i = 0; i < _countof(IniFileParameterList); i++)
  568. {
  569. if (strncasecmp(IniFileParameterList[i].Name, s, strlen(IniFileParameterList[i].Name))) continue;
  570. if (!IniFileParameterList[i].Id) return TRUE;
  571. if (!getIniFileArgument(&s)) return FALSE;
  572. return setIniFileParameter(IniFileParameterList[i].Id, s);
  573. }
  574. IniFileErrorMessage = "Unknown keyword.";
  575. return FALSE;
  576. }
  577. #if !defined(NO_SOCKETS) && !defined(USE_MSRPC)
  578. static BOOL setupListeningSocketsFromIniFile(const char *s)
  579. {
  580. if (!maxsockets) return TRUE;
  581. if (strncasecmp("Listen", s, 6)) return TRUE;
  582. if (!getIniFileArgument(&s)) return TRUE;
  583. snprintf(IniFileErrorBuffer, INIFILE_ERROR_BUFFERSIZE, "Cannot listen on %s.", s);
  584. IniFileErrorMessage = IniFileErrorBuffer;
  585. return addListeningSocket(s);
  586. }
  587. #endif // !defined(NO_SOCKETS) && !defined(USE_MSRPC)
  588. static BOOL readIniFile(const uint_fast8_t pass)
  589. {
  590. char line[256];
  591. const char *s;
  592. ProdListIndex_t appIndex;
  593. unsigned int lineNumber;
  594. uint_fast8_t lineParseError;
  595. FILE *restrict f;
  596. BOOL result = TRUE;
  597. IniFileErrorBuffer = (char*)vlmcsd_malloc(INIFILE_ERROR_BUFFERSIZE);
  598. if ( !(f = fopen(fn_ini, "r") )) return FALSE;
  599. for (lineNumber = 1; (s = fgets(line, sizeof(line), f)); lineNumber++)
  600. {
  601. line[strlen(line) - 1] = 0;
  602. iniFileLineNextWord(&s);
  603. if (*s == ';' || *s == '#' || !*s) continue;
  604. # ifndef NO_SOCKETS
  605. if (pass == INI_FILE_PASS_1)
  606. # endif // NO_SOCKETS
  607. {
  608. if (handleIniFileParameter(s)) continue;
  609. lineParseError = !checkGuidInIniFileLine(&s, &appIndex) ||
  610. !setEpidFromIniFileLine(&s, appIndex) ||
  611. !setHwIdFromIniFileLine(&s, appIndex);
  612. }
  613. # if !defined(NO_SOCKETS) && !defined(USE_MSRPC)
  614. else if (pass == INI_FILE_PASS_2)
  615. {
  616. lineParseError = !setupListeningSocketsFromIniFile(s);
  617. }
  618. else
  619. {
  620. return FALSE;
  621. }
  622. # endif // NO_SOCKETS
  623. if (lineParseError)
  624. {
  625. printerrorf("Warning: %s line %u: \"%s\". %s\n", fn_ini, lineNumber, line, IniFileErrorMessage);
  626. continue;
  627. }
  628. }
  629. if (ferror(f)) result = FALSE;
  630. free(IniFileErrorBuffer);
  631. fclose(f);
  632. # if !defined(NO_SOCKETS) && !defined(NO_LOG)
  633. if (pass == INI_FILE_PASS_1 && !InetdMode && result)
  634. {
  635. # ifdef _NTSERVICE
  636. if (!installService)
  637. # endif // _NTSERVICE
  638. logger("Read ini file %s\n", fn_ini);
  639. }
  640. # endif // !defined(NO_SOCKETS) && !defined(NO_LOG)
  641. return result;
  642. }
  643. #endif // NO_INI_FILE
  644. #if !defined(NO_SOCKETS)
  645. #if !defined(_WIN32)
  646. #if !defined(NO_SIGHUP)
  647. static void exec_self(char** argv)
  648. {
  649. # if __linux__ && defined(USE_AUXV)
  650. char *execname_ptr = (char*)getauxval(AT_EXECFN);
  651. if (execname_ptr) execv(execname_ptr, argv);
  652. # elif (__linux__ || __CYGWIN__) && !defined(NO_PROCFS)
  653. execv(realpath("/proc/self/exe", NULL), argv);
  654. # elif (__FreeBSD__) && !defined(NO_PROCFS)
  655. int mib[4];
  656. mib[0] = CTL_KERN;
  657. mib[1] = KERN_PROC;
  658. mib[2] = KERN_PROC_PATHNAME;
  659. mib[3] = -1;
  660. char path[PATH_MAX + 1];
  661. size_t cb = sizeof(path);
  662. if (!sysctl(mib, 4, path, &cb, NULL, 0)) execv(path, argv);
  663. # elif (__DragonFly__) && !defined(NO_PROCFS)
  664. execv(realpath("/proc/curproc/file", NULL), argv);
  665. # elif __NetBSD__ && !defined(NO_PROCFS)
  666. execv(realpath("/proc/curproc/exe", NULL), argv);
  667. # elif __sun__
  668. const char* exename = getexecname();
  669. if (exename) execv(exename, argv);
  670. # elif __APPLE__
  671. char path[PATH_MAX + 1];
  672. uint32_t size = sizeof(path);
  673. if (_NSGetExecutablePath(path, &size) == 0) execv(path, argv);
  674. # else
  675. execvp(argv[0], argv);
  676. # endif
  677. }
  678. static void HangupHandler(const int signal_unused)
  679. {
  680. int i;
  681. int_fast8_t daemonize_protection = TRUE;
  682. CARGV argv_in = multi_argv == NULL ? global_argv : multi_argv;
  683. int argc_in = multi_argc == 0 ? global_argc : multi_argc;
  684. const char** argv_out = (const char**)vlmcsd_malloc((argc_in + 2) * sizeof(char**));
  685. for (i = 0; i < argc_in; i++)
  686. {
  687. if (!strcmp(argv_in[i], "-Z")) daemonize_protection = FALSE;
  688. argv_out[i] = argv_in[i];
  689. }
  690. argv_out[argc_in] = argv_out[argc_in + 1] = NULL;
  691. if (daemonize_protection) argv_out[argc_in] = (char*) "-Z";
  692. exec_self((char**)argv_out);
  693. # ifndef NO_LOG
  694. logger("Fatal: Unable to restart on SIGHUP: %s\n", strerror(errno));
  695. # endif
  696. # ifndef NO_PID_FILE
  697. if (fn_pid) unlink(fn_pid);
  698. # endif // NO_PID_FILE
  699. exit(errno);
  700. }
  701. #endif // NO_SIGHUP
  702. static void terminationHandler(const int signal_unused)
  703. {
  704. cleanup();
  705. exit(0);
  706. }
  707. #if defined(CHILD_HANDLER) || __minix__
  708. static void childHandler(const int signal)
  709. {
  710. waitpid(-1, NULL, WNOHANG);
  711. }
  712. #endif // defined(CHILD_HANDLER) || __minix__
  713. static int daemonizeAndSetSignalAction()
  714. {
  715. struct sigaction sa;
  716. sigemptyset(&sa.sa_mask);
  717. # ifndef NO_LOG
  718. if ( !nodaemon) if (daemon(!0, logstdout))
  719. # else // NO_LOG
  720. if ( !nodaemon) if (daemon(!0, 0))
  721. # endif // NO_LOG
  722. {
  723. printerrorf("Fatal: Could not daemonize to background.\n");
  724. return(errno);
  725. }
  726. if (!InetdMode)
  727. {
  728. # ifndef USE_THREADS
  729. # if defined(CHILD_HANDLER) || __minix__
  730. sa.sa_handler = childHandler;
  731. # else // !(defined(CHILD_HANDLER) || __minix__)
  732. sa.sa_handler = SIG_IGN;
  733. # endif // !(defined(CHILD_HANDLER) || __minix__)
  734. sa.sa_flags = SA_NOCLDWAIT;
  735. if (sigaction(SIGCHLD, &sa, NULL))
  736. return(errno);
  737. # endif // !USE_THREADS
  738. sa.sa_handler = terminationHandler;
  739. sa.sa_flags = 0;
  740. sigaction(SIGINT, &sa, NULL);
  741. sigaction(SIGTERM, &sa, NULL);
  742. # ifndef NO_SIGHUP
  743. sa.sa_handler = HangupHandler;
  744. sa.sa_flags = SA_NODEFER;
  745. sigaction(SIGHUP, &sa, NULL);
  746. # endif // NO_SIGHUP
  747. }
  748. return 0;
  749. }
  750. #else // _WIN32
  751. static BOOL terminationHandler(const DWORD fdwCtrlType)
  752. {
  753. // What a lame substitute for Unix signal handling
  754. switch(fdwCtrlType)
  755. {
  756. case CTRL_C_EVENT:
  757. case CTRL_CLOSE_EVENT:
  758. case CTRL_BREAK_EVENT:
  759. case CTRL_LOGOFF_EVENT:
  760. case CTRL_SHUTDOWN_EVENT:
  761. cleanup();
  762. exit(0);
  763. default:
  764. return FALSE;
  765. }
  766. }
  767. static DWORD daemonizeAndSetSignalAction()
  768. {
  769. if(!SetConsoleCtrlHandler( (PHANDLER_ROUTINE) terminationHandler, TRUE ))
  770. {
  771. #ifndef NO_LOG
  772. DWORD rc = GetLastError();
  773. logger("Warning: Could not register Windows signal handler: Error %u\n", rc);
  774. #endif // NO_LOG
  775. }
  776. return ERROR_SUCCESS;
  777. }
  778. #endif // _WIN32
  779. #endif // !defined(NO_SOCKETS)
  780. // Workaround for Cygwin fork bug (only affects cygwin processes that are Windows services)
  781. // Best is to compile for Cygwin with threads. fork() is slow and unreliable on Cygwin
  782. #if !defined(NO_INI_FILE) || !defined(NO_LOG) || !defined(NO_CL_PIDS)
  783. __pure static char* getCommandLineArg(char *const restrict optarg)
  784. {
  785. #if !defined (__CYGWIN__) || defined(USE_THREADS) || defined(NO_SOCKETS)
  786. return optarg;
  787. #else
  788. if (!IsNTService) return optarg;
  789. return allocateStringArgument(optarg);
  790. #endif
  791. }
  792. #endif // !defined(NO_INI_FILE) || !defined(NO_LOG) || !defined(NO_CL_PIDS)
  793. static void parseGeneralArguments() {
  794. int o;
  795. #ifndef NO_CL_PIDS
  796. BYTE* HwId;
  797. #endif // NO_CL_PIDS
  798. for (opterr = 0; ( o = getopt(global_argc, (char* const*)global_argv, optstring) ) > 0; ) switch (o)
  799. {
  800. #if !defined(NO_SOCKETS) && !defined(NO_SIGHUP) && !defined(_WIN32)
  801. case 'Z':
  802. IsRestarted = TRUE;
  803. nodaemon = TRUE;
  804. break;
  805. #endif // !defined(NO_SOCKETS) && !defined(NO_SIGHUP) && !defined(_WIN32)
  806. #ifndef NO_CL_PIDS
  807. case 'w':
  808. KmsResponseParameters[APP_ID_WINDOWS].Epid = getCommandLineArg(optarg);
  809. #ifndef NO_LOG
  810. KmsResponseParameters[APP_ID_WINDOWS].EpidSource = "command line";
  811. #endif // NO_LOG
  812. break;
  813. case '0':
  814. KmsResponseParameters[APP_ID_OFFICE2010].Epid = getCommandLineArg(optarg);
  815. #ifndef NO_LOG
  816. KmsResponseParameters[APP_ID_OFFICE2010].EpidSource = "command line";
  817. #endif // NO_LOG
  818. break;
  819. case '3':
  820. KmsResponseParameters[APP_ID_OFFICE2013].Epid = getCommandLineArg(optarg);
  821. #ifndef NO_LOG
  822. KmsResponseParameters[APP_ID_OFFICE2013].EpidSource = "command line";
  823. #endif // NO_LOG
  824. break;
  825. case 'H':
  826. HwId = (BYTE*)vlmcsd_malloc(sizeof(((RESPONSE_V6 *)0)->HwId));
  827. hex2bin(HwId, optarg, sizeof(((RESPONSE_V6 *)0)->HwId));
  828. KmsResponseParameters[APP_ID_WINDOWS].HwId = HwId;
  829. KmsResponseParameters[APP_ID_OFFICE2010].HwId = HwId;
  830. KmsResponseParameters[APP_ID_OFFICE2013].HwId = HwId;
  831. break;
  832. #endif // NO_CL_PIDS
  833. #ifndef NO_SOCKETS
  834. #ifndef USE_MSRPC
  835. case '4':
  836. case '6':
  837. case 'P':
  838. ignoreIniFileParameter(INI_PARAM_LISTEN);
  839. break;
  840. #else // USE_MSRPC
  841. case 'P':
  842. defaultport = optarg;
  843. ignoreIniFileParameter(INI_PARAM_PORT);
  844. break;
  845. #endif // USE_MSRPC
  846. #if !defined(NO_LIMIT) && !__minix__
  847. case 'm':
  848. #ifdef USE_MSRPC
  849. MaxTasks = getOptionArgumentInt(o, 1, RPC_C_LISTEN_MAX_CALLS_DEFAULT);
  850. #else // !USE_MSRPC
  851. MaxTasks = getOptionArgumentInt(o, 1, SEM_VALUE_MAX);
  852. #endif // !USE_MSRPC
  853. ignoreIniFileParameter(INI_PARAM_MAX_WORKERS);
  854. break;
  855. #endif // !defined(NO_LIMIT) && !__minix__
  856. #endif // NO_SOCKETS
  857. #if !defined(NO_TIMEOUT) && !__minix__ && !defined(USE_MSRPC)
  858. case 't':
  859. ServerTimeout = getOptionArgumentInt(o, 1, 600);
  860. ignoreIniFileParameter(INI_PARAM_CONNECTION_TIMEOUT);
  861. break;
  862. #endif // !defined(NO_TIMEOUT) && !__minix__ && !defined(USE_MSRPC)
  863. #ifndef NO_PID_FILE
  864. case 'p':
  865. fn_pid = getCommandLineArg(optarg);
  866. ignoreIniFileParameter(INI_PARAM_PID_FILE);
  867. break;
  868. #endif
  869. #ifndef NO_INI_FILE
  870. case 'i':
  871. fn_ini = getCommandLineArg(optarg);
  872. if (!strcmp(fn_ini, "-")) fn_ini = NULL;
  873. break;
  874. #endif
  875. #ifndef NO_LOG
  876. case 'l':
  877. fn_log = getCommandLineArg(optarg);
  878. ignoreIniFileParameter(INI_PARAM_LOG_FILE);
  879. break;
  880. #ifndef NO_VERBOSE_LOG
  881. case 'v':
  882. case 'q':
  883. logverbose = o == 'v';
  884. ignoreIniFileParameter(INI_PARAM_LOG_VERBOSE);
  885. break;
  886. #endif // NO_VERBOSE_LOG
  887. #endif // NO_LOG
  888. #ifndef NO_SOCKETS
  889. #ifndef USE_MSRPC
  890. case 'L':
  891. maxsockets++;
  892. ignoreIniFileParameter(INI_PARAM_LISTEN);
  893. break;
  894. #endif // USE_MSRPC
  895. case 'f':
  896. nodaemon = 1;
  897. #ifndef NO_LOG
  898. logstdout = 1;
  899. #endif
  900. break;
  901. #ifdef _NTSERVICE
  902. case 'U':
  903. ServiceUser = optarg;
  904. break;
  905. case 'W':
  906. ServicePassword = optarg;
  907. break;
  908. case 's':
  909. #ifndef USE_MSRPC
  910. if (InetdMode) usage();
  911. #endif // USE_MSRPC
  912. if (!IsNTService) installService = 1; // Install
  913. break;
  914. case 'S':
  915. if (!IsNTService) installService = 2; // Remove
  916. break;
  917. #endif // _NTSERVICE
  918. case 'D':
  919. nodaemon = 1;
  920. break;
  921. #ifndef NO_LOG
  922. case 'e':
  923. logstdout = 1;
  924. break;
  925. #endif // NO_LOG
  926. #endif // NO_SOCKETS
  927. #ifndef _WIN32
  928. case 'I': // Backward compatibility with svn681 and earlier
  929. break;
  930. #endif // _WIN32
  931. #ifndef NO_RANDOM_EPID
  932. case 'r':
  933. RandomizationLevel = (int_fast8_t)getOptionArgumentInt(o, 0, 2);
  934. ignoreIniFileParameter(INI_PARAM_RANDOMIZATION_LEVEL);
  935. break;
  936. case 'C':
  937. Lcid = (uint16_t)getOptionArgumentInt(o, 0, 32767);
  938. ignoreIniFileParameter(INI_PARAM_LCID);
  939. #ifdef _PEDANTIC
  940. if (!IsValidLcid(Lcid))
  941. {
  942. printerrorf("Warning: %s is not a valid LCID.\n", optarg);
  943. }
  944. #endif // _PEDANTIC
  945. break;
  946. #endif // NO_RANDOM_PID
  947. #if !defined(NO_USER_SWITCH) && !defined(_WIN32)
  948. case 'g':
  949. gname = optarg;
  950. ignoreIniFileParameter(INI_PARAM_GID);
  951. #ifndef NO_SIGHUP
  952. if (!IsRestarted)
  953. #endif // NO_SIGHUP
  954. if (GetGid())
  955. {
  956. printerrorf("Fatal: setgid for %s failed.\n", optarg);
  957. exit(!0);
  958. }
  959. break;
  960. case 'u':
  961. uname = optarg;
  962. ignoreIniFileParameter(INI_PARAM_UID);
  963. #ifndef NO_SIGHUP
  964. if (!IsRestarted)
  965. #endif // NO_SIGHUP
  966. if (GetUid())
  967. {
  968. printerrorf("Fatal: setuid for %s failed.\n", optarg);
  969. exit(!0);
  970. }
  971. break;
  972. #endif // NO_USER_SWITCH && !_WIN32
  973. #ifndef NO_CUSTOM_INTERVALS
  974. case 'R':
  975. VLRenewalInterval = getTimeSpanFromCommandLine(optarg, o);
  976. ignoreIniFileParameter(INI_PARAM_RENEWAL_INTERVAL);
  977. break;
  978. case 'A':
  979. VLActivationInterval = getTimeSpanFromCommandLine(optarg, o);
  980. ignoreIniFileParameter(INI_PARAM_ACTIVATION_INTERVAL);
  981. break;
  982. #endif
  983. #ifndef USE_MSRPC
  984. case 'd':
  985. case 'k':
  986. DisconnectImmediately = o == 'd';
  987. ignoreIniFileParameter(INI_PARAM_DISCONNECT_IMMEDIATELY);
  988. break;
  989. case 'N':
  990. if (!getArgumentBool(&UseRpcNDR64, optarg)) usage();
  991. ignoreIniFileParameter(INI_PARAM_RPC_NDR64);
  992. break;
  993. case 'B':
  994. if (!getArgumentBool(&UseRpcBTFN, optarg)) usage();
  995. ignoreIniFileParameter(INI_PARAM_RPC_BTFN);
  996. break;
  997. #endif // !USE_MSRPC
  998. case 'V':
  999. #ifdef _NTSERVICE
  1000. if (IsNTService) break;
  1001. #endif
  1002. printf("vlmcsd %s\n", Version);
  1003. exit(0);
  1004. default:
  1005. usage();
  1006. }
  1007. // Do not allow non-option arguments
  1008. if (optind != global_argc)
  1009. usage();
  1010. #ifdef _NTSERVICE
  1011. // -U and -W must be used with -s
  1012. if ((ServiceUser || *ServicePassword) && installService != 1) usage();
  1013. #endif // _NTSERVICE
  1014. }
  1015. #ifndef NO_PID_FILE
  1016. static void writePidFile()
  1017. {
  1018. # ifndef NO_SIGHUP
  1019. if (IsRestarted) return;
  1020. # endif // NO_SIGHUP
  1021. if (fn_pid && !InetdMode)
  1022. {
  1023. FILE *_f = fopen(fn_pid, "w");
  1024. if ( _f )
  1025. {
  1026. fprintf(_f, "%u", (uint32_t)getpid());
  1027. fclose(_f);
  1028. }
  1029. #ifndef NO_LOG
  1030. else
  1031. {
  1032. logger("Warning: Cannot write pid file '%s'. %s.\n", fn_pid, strerror(errno));
  1033. }
  1034. #endif // NO_LOG
  1035. }
  1036. }
  1037. #else
  1038. #define writePidFile(x)
  1039. #endif // NO_PID_FILE
  1040. #if !defined(NO_SOCKETS) && !defined(USE_MSRPC)
  1041. void cleanup()
  1042. {
  1043. if (!InetdMode)
  1044. {
  1045. #ifndef NO_PID_FILE
  1046. if (fn_pid) unlink(fn_pid);
  1047. #endif // NO_PID_FILE
  1048. closeAllListeningSockets();
  1049. #if !defined(NO_LIMIT) && !defined(NO_SOCKETS) && !defined(_WIN32) && !__minix__
  1050. sem_unlink("/vlmcsd");
  1051. #if !defined(USE_THREADS) && !defined(CYGWIN)
  1052. if (shmid >= 0)
  1053. {
  1054. if (Semaphore != (sem_t*)-1) shmdt(Semaphore);
  1055. shmctl(shmid, IPC_RMID, NULL);
  1056. }
  1057. #endif // !defined(USE_THREADS) && !defined(CYGWIN)
  1058. #endif // !defined(NO_LIMIT) && !defined(NO_SOCKETS) && !defined(_WIN32) && !__minix__
  1059. #ifndef NO_LOG
  1060. logger("vlmcsd %s was shutdown\n", Version);
  1061. #endif // NO_LOG
  1062. }
  1063. }
  1064. #elif defined(USE_MSRPC)
  1065. void cleanup()
  1066. {
  1067. # ifndef NO_PID_FILE
  1068. if (fn_pid) unlink(fn_pid);
  1069. # endif // NO_PID_FILE
  1070. # ifndef NO_LOG
  1071. logger("vlmcsd %s was shutdown\n", Version);
  1072. # endif // NO_LOG
  1073. }
  1074. #else // Neither Sockets nor RPC
  1075. __pure void cleanup() {}
  1076. #endif // Neither Sockets nor RPC
  1077. #if !defined(USE_MSRPC) && !defined(NO_LIMIT) && !defined(NO_SOCKETS) && !__minix__
  1078. // Get a semaphore for limiting the maximum concurrent tasks
  1079. static void allocateSemaphore(void)
  1080. {
  1081. #ifdef USE_THREADS
  1082. #define sharemode 0
  1083. #else
  1084. #define sharemode 1
  1085. #endif
  1086. #ifndef _WIN32
  1087. sem_unlink("/vlmcsd");
  1088. #endif
  1089. if(MaxTasks < SEM_VALUE_MAX && !InetdMode)
  1090. {
  1091. #ifndef _WIN32
  1092. #if !defined(USE_THREADS) && !defined(CYGWIN)
  1093. if ((Semaphore = sem_open("/vlmcsd", O_CREAT /*| O_EXCL*/, 0700, MaxTasks)) == SEM_FAILED) // fails on many systems
  1094. {
  1095. // We didn't get a named Semaphore (/dev/shm on Linux) so let's try our own shared page
  1096. if (
  1097. ( shmid = shmget(IPC_PRIVATE, sizeof(sem_t), IPC_CREAT | 0600) ) < 0 ||
  1098. ( Semaphore = (sem_t*)shmat(shmid, NULL, 0) ) == (sem_t*)-1 ||
  1099. sem_init(Semaphore, 1, MaxTasks) < 0
  1100. )
  1101. {
  1102. int errno_save = errno;
  1103. if (Semaphore != (sem_t*)-1) shmdt(Semaphore);
  1104. if (shmid >= 0) shmctl(shmid, IPC_RMID, NULL);
  1105. printerrorf("Warning: Could not create semaphore: %s\n", vlmcsd_strerror(errno_save));
  1106. MaxTasks = SEM_VALUE_MAX;
  1107. }
  1108. }
  1109. #else // THREADS or CYGWIN
  1110. Semaphore = (sem_t*)vlmcsd_malloc(sizeof(sem_t));
  1111. if (sem_init(Semaphore, sharemode, MaxTasks) < 0) // sem_init is not implemented on Darwin (returns ENOSYS)
  1112. {
  1113. free(Semaphore);
  1114. if ((Semaphore = sem_open("/vlmcsd", O_CREAT /*| O_EXCL*/, 0700, MaxTasks)) == SEM_FAILED)
  1115. {
  1116. printerrorf("Warning: Could not create semaphore: %s\n", vlmcsd_strerror(errno));
  1117. MaxTasks = SEM_VALUE_MAX;
  1118. }
  1119. }
  1120. #endif // THREADS or CYGWIN
  1121. #else // _WIN32
  1122. if (!(Semaphore = CreateSemaphoreA(NULL, MaxTasks, MaxTasks, NULL)))
  1123. {
  1124. printerrorf("Warning: Could not create semaphore: %s\n", vlmcsd_strerror(GetLastError()));
  1125. MaxTasks = SEM_VALUE_MAX;
  1126. }
  1127. #endif // _WIN32
  1128. }
  1129. }
  1130. #endif // !defined(NO_LIMIT) && !defined(NO_SOCKETS) && !__minix__
  1131. #if !defined(NO_SOCKETS) && !defined(USE_MSRPC)
  1132. int setupListeningSockets()
  1133. {
  1134. int o;
  1135. uint_fast8_t allocsockets = maxsockets ? maxsockets : 2;
  1136. SocketList = (SOCKET*)vlmcsd_malloc((size_t)allocsockets * sizeof(SOCKET));
  1137. haveIPv4Stack = checkProtocolStack(AF_INET);
  1138. haveIPv6Stack = checkProtocolStack(AF_INET6);
  1139. // Reset getopt since we've alread used it
  1140. optReset();
  1141. for (opterr = 0; ( o = getopt(global_argc, (char* const*)global_argv, optstring) ) > 0; ) switch (o)
  1142. {
  1143. case '4':
  1144. if (!haveIPv4Stack)
  1145. {
  1146. printerrorf("Fatal: Your system does not support %s.\n", cIPv4);
  1147. return !0;
  1148. }
  1149. v4required = 1;
  1150. break;
  1151. case '6':
  1152. if (!haveIPv6Stack)
  1153. {
  1154. printerrorf("Fatal: Your system does not support %s.\n", cIPv6);
  1155. return !0;
  1156. }
  1157. v6required = 1;
  1158. break;
  1159. case 'L':
  1160. addListeningSocket(optarg);
  1161. break;
  1162. case 'P':
  1163. defaultport = optarg;
  1164. break;
  1165. default:
  1166. break;
  1167. }
  1168. # ifndef NO_INI_FILE
  1169. if (maxsockets && !numsockets)
  1170. {
  1171. if (fn_ini && !readIniFile(INI_FILE_PASS_2))
  1172. {
  1173. #ifdef INI_FILE
  1174. if (strcmp(fn_ini, INI_FILE))
  1175. #endif // INI_FILE
  1176. printerrorf("Warning: Can't read %s: %s\n", fn_ini, strerror(errno));
  1177. }
  1178. }
  1179. # endif
  1180. // if -L hasn't been specified on the command line, use default sockets (all IP addresses)
  1181. // maxsocket results from first pass parsing the arguments
  1182. if (!maxsockets)
  1183. {
  1184. if (haveIPv6Stack && (v6required || !v4required)) addListeningSocket("::");
  1185. if (haveIPv4Stack && (v4required || !v6required)) addListeningSocket("0.0.0.0");
  1186. }
  1187. if (!numsockets)
  1188. {
  1189. printerrorf("Fatal: Could not listen on any socket.\n");
  1190. return(!0);
  1191. }
  1192. return 0;
  1193. }
  1194. #endif // !defined(NO_SOCKETS) && !defined(USE_MSRPC)
  1195. int server_main(int argc, CARGV argv)
  1196. {
  1197. #if !defined(_NTSERVICE) && !defined(NO_SOCKETS)
  1198. int error;
  1199. #endif // !defined(_NTSERVICE) && !defined(NO_SOCKETS)
  1200. // Initialize ePID / HwId parameters
  1201. memset(KmsResponseParameters, 0, sizeof(KmsResponseParameters));
  1202. global_argc = argc;
  1203. global_argv = argv;
  1204. #ifdef _NTSERVICE // #endif is in newmain()
  1205. DWORD lasterror = ERROR_SUCCESS;
  1206. if (!StartServiceCtrlDispatcher(NTServiceDispatchTable) && (lasterror = GetLastError()) == ERROR_FAILED_SERVICE_CONTROLLER_CONNECT)
  1207. {
  1208. IsNTService = FALSE;
  1209. return newmain();
  1210. }
  1211. return lasterror;
  1212. }
  1213. int newmain()
  1214. {
  1215. int error;
  1216. // Initialize thread synchronization objects for Windows and Cygwin
  1217. #ifdef USE_THREADS
  1218. #ifndef NO_LOG
  1219. // Initialize the Critical Section for proper logging
  1220. InitializeCriticalSection(&logmutex);
  1221. #endif // NO_LOG
  1222. #endif // USE_THREADS
  1223. #ifdef _WIN32
  1224. #ifndef USE_MSRPC
  1225. // Windows Sockets must be initialized
  1226. WSADATA wsadata;
  1227. if ((error = WSAStartup(0x0202, &wsadata)))
  1228. {
  1229. printerrorf("Fatal: Could not initialize Windows sockets (Error: %d).\n", error);
  1230. return error;
  1231. }
  1232. #endif // USE_MSRPC
  1233. // Windows can never daemonize
  1234. nodaemon = 1;
  1235. #else // __CYGWIN__
  1236. // Do not daemonize if we are a Windows service
  1237. if (IsNTService) nodaemon = 1;
  1238. #endif // _WIN32 / __CYGWIN__
  1239. #endif // _NTSERVICE ( #ifdef is main(int argc, CARGV argv) )
  1240. parseGeneralArguments(); // Does not return if an error occurs
  1241. #if !defined(_WIN32) && !defined(NO_SOCKETS) && !defined(USE_MSRPC)
  1242. struct stat statbuf;
  1243. fstat(STDIN_FILENO, &statbuf);
  1244. if (S_ISSOCK(statbuf.st_mode))
  1245. {
  1246. InetdMode = 1;
  1247. nodaemon = 1;
  1248. maxsockets = 0;
  1249. #ifndef NO_LOG
  1250. logstdout = 0;
  1251. #endif // NO_LOG
  1252. }
  1253. #endif // !defined(_WIN32) && !defined(NO_SOCKETS) && !defined(USE_MSRPC)
  1254. #ifndef NO_INI_FILE
  1255. if (fn_ini && !readIniFile(INI_FILE_PASS_1))
  1256. {
  1257. #ifdef INI_FILE
  1258. if (strcmp(fn_ini, INI_FILE))
  1259. #endif // INI_FILE
  1260. printerrorf("Warning: Can't read %s: %s\n", fn_ini, strerror(errno));
  1261. }
  1262. #endif // NO_INI_FILE
  1263. #if !defined(NO_LIMIT) && !defined(NO_SOCKETS) && !__minix__ && !defined(USE_MSRPC)
  1264. allocateSemaphore();
  1265. #endif // !defined(NO_LIMIT) && !defined(NO_SOCKETS) && __minix__
  1266. #ifdef _NTSERVICE
  1267. if (installService)
  1268. return NtServiceInstallation(installService, ServiceUser, ServicePassword);
  1269. #endif // _NTSERVICE
  1270. #if !defined(NO_SOCKETS) && !defined(USE_MSRPC)
  1271. if (!InetdMode)
  1272. {
  1273. if ((error = setupListeningSockets())) return error;
  1274. }
  1275. #endif // NO_SOCKETS
  1276. // After sockets have been set up, we may switch to a lower privileged user
  1277. #if !defined(_WIN32) && !defined(NO_USER_SWITCH)
  1278. #ifndef NO_SIGHUP
  1279. if (!IsRestarted)
  1280. {
  1281. #endif // NO_SIGHUP
  1282. if (gid != INVALID_GID && setgid(gid))
  1283. {
  1284. printerrorf("Fatal: setgid for %s failed.\n", gname);
  1285. return !0;
  1286. }
  1287. if (uid != INVALID_UID && setuid(uid))
  1288. {
  1289. printerrorf("Fatal: setuid for %s failed.\n", uname);
  1290. return !0;
  1291. }
  1292. #ifndef NO_SIGHUP
  1293. }
  1294. #endif // NO_SIGHUP
  1295. #endif // !defined(_WIN32) && !defined(NO_USER_SWITCH)
  1296. randomNumberInit();
  1297. // Randomization Level 1 means generate ePIDs at startup and use them during
  1298. // the lifetime of the process. So we generate them now
  1299. #ifndef NO_RANDOM_EPID
  1300. if (RandomizationLevel == 1) randomPidInit();
  1301. #endif
  1302. #if !defined(NO_SOCKETS)
  1303. #ifdef _WIN32
  1304. if (!IsNTService)
  1305. #endif // _WIN32
  1306. if ((error = daemonizeAndSetSignalAction())) return error;
  1307. #endif // !defined(NO_SOCKETS)
  1308. writePidFile();
  1309. #if !defined(NO_LOG) && !defined(NO_SOCKETS) && !defined(USE_MSRPC)
  1310. if (!InetdMode)
  1311. logger("vlmcsd %s started successfully\n", Version);
  1312. #endif // !defined(NO_LOG) && !defined(NO_SOCKETS) && !defined(USE_MSRPC)
  1313. #if defined(_NTSERVICE) && !defined(USE_MSRPC)
  1314. if (IsNTService) ReportServiceStatus(SERVICE_RUNNING, NO_ERROR, 200);
  1315. #endif // defined(_NTSERVICE) && !defined(USE_MSRPC)
  1316. int rc;
  1317. rc = runServer();
  1318. // Clean up things and exit
  1319. #ifdef _NTSERVICE
  1320. if (!ServiceShutdown)
  1321. #endif
  1322. cleanup();
  1323. #ifdef _NTSERVICE
  1324. else
  1325. ReportServiceStatus(SERVICE_STOPPED, NO_ERROR, 0);
  1326. #endif
  1327. return rc;
  1328. }
  1329. #ifndef CONFIG
  1330. #define CONFIG "config.h"
  1331. #endif // CONFIG
  1332. #include CONFIG
  1333. #ifndef _GNU_SOURCE
  1334. #define _GNU_SOURCE
  1335. #endif
  1336. #include "vlmcs.h"
  1337. #include <stdio.h>
  1338. #include <stdlib.h>
  1339. #include <string.h>
  1340. #include <errno.h>
  1341. #include <stdint.h>
  1342. #include <getopt.h>
  1343. #include <sys/types.h>
  1344. #include <sys/stat.h>
  1345. #include <unistd.h>
  1346. #ifndef _WIN32
  1347. #include <sys/ioctl.h>
  1348. #include <termios.h>
  1349. #else // _WIN32
  1350. #endif // _WIN32
  1351. #include "endian.h"
  1352. #include "shared_globals.h"
  1353. #include "output.h"
  1354. #ifndef USE_MSRPC
  1355. #include "network.h"
  1356. #include "rpc.h"
  1357. #else // USE_MSRPC
  1358. #include "msrpc-client.h"
  1359. #endif // USE_MSRPC
  1360. #include "kms.h"
  1361. #include "helpers.h"
  1362. #include "dns_srv.h"
  1363. #define VLMCS_OPTION_GRAB_INI 1
  1364. #define VLMCS_OPTION_NO_GRAB_INI 2
  1365. #define kmsVersionMinor 0 // Currently constant. May change in future KMS versions
  1366. // Function Prototypes
  1367. static void CreateRequestBase(REQUEST *Request);
  1368. // KMS Parameters
  1369. static int_fast8_t verbose = FALSE;
  1370. static int_fast8_t VMInfo = FALSE;
  1371. static int_fast8_t dnsnames = TRUE;
  1372. static int FixedRequests = 0;
  1373. static BYTE LicenseStatus = 0x02;
  1374. static const char *CMID = NULL;
  1375. static const char *CMID_prev = NULL;
  1376. static const char *WorkstationName = NULL;
  1377. static int BindingExpiration = 43200; //30 days
  1378. static const char *RemoteAddr;
  1379. static int_fast8_t ReconnectForEachRequest = FALSE;
  1380. static int AddressFamily = AF_UNSPEC;
  1381. static int_fast8_t incompatibleOptions = 0;
  1382. static const char* fn_ini_client = NULL;
  1383. #ifndef NO_DNS
  1384. static int_fast8_t NoSrvRecordPriority = FALSE;
  1385. #endif // NO_DNS
  1386. // Structure for handling "License Packs" (e.g. Office2013v5 or WindowsVista)
  1387. typedef struct
  1388. {
  1389. const char *names; //This is a list of strings. Terminate with additional Zero!!!
  1390. int N_Policy;
  1391. int kmsVersionMajor;
  1392. const GUID *AppID;
  1393. GUID ActID;
  1394. GUID KMSID;
  1395. } LicensePack;
  1396. typedef char iniFileEpidLines[3][256];
  1397. // Well known "license packs"
  1398. static const LicensePack LicensePackList[] =
  1399. {
  1400. // List of names min lics version appID skuId KMSCountedID
  1401. /* 000 */ { "Vista\000W6\000"
  1402. "WindowsVista\000"
  1403. "Windows\000", 25, 4, PWINGUID, { 0x4f3d1606, 0x3fea, 0x4c01, { 0xbe, 0x3c, 0x8d, 0x67, 0x1c, 0x40, 0x1e, 0x3b, } }, { 0x212a64dc, 0x43b1, 0x4d3d, { 0xa3, 0x0c, 0x2f, 0xc6, 0x9d, 0x20, 0x95, 0xc6 } } },
  1404. /* 001 */ { "W7\000Windows7\000", 25, 4, PWINGUID, { 0xb92e9980, 0xb9d5, 0x4821, { 0x9c, 0x94, 0x14, 0x0f, 0x63, 0x2f, 0x63, 0x12, } }, { 0x7fde5219, 0xfbfa, 0x484a, { 0x82, 0xc9, 0x34, 0xd1, 0xad, 0x53, 0xe8, 0x56 } } },
  1405. /* 002 */ { "W8\000Windows8\000", 25, 5, PWINGUID, { 0xa98bcd6d, 0x5343, 0x4603, { 0x8a, 0xfe, 0x59, 0x08, 0xe4, 0x61, 0x11, 0x12, } }, { 0x3c40b358, 0x5948, 0x45af, { 0x92, 0x3b, 0x53, 0xd2, 0x1f, 0xcc, 0x7e, 0x79 } } },
  1406. /* 003 */ { "W8C\000Windows8C\000", 25, 5, PWINGUID, { 0xc04ed6bf, 0x55c8, 0x4b47, { 0x9f, 0x8e, 0x5a, 0x1f, 0x31, 0xce, 0xee, 0x60, } }, { 0xbbb97b3b, 0x8ca4, 0x4a28, { 0x97, 0x17, 0x89, 0xfa, 0xbd, 0x42, 0xc4, 0xac } } },
  1407. /* 004 */ { "W81\000Windows81\000", 25, 6, PWINGUID, { 0xc06b6981, 0xd7fd, 0x4a35, { 0xb7, 0xb4, 0x05, 0x47, 0x42, 0xb7, 0xaf, 0x67, } }, { 0xcb8fc780, 0x2c05, 0x495a, { 0x97, 0x10, 0x85, 0xaf, 0xff, 0xc9, 0x04, 0xd7 } } },
  1408. /* 005 */ { "W81C\000Windows81C\000", 25, 6, PWINGUID, { 0xfe1c3238, 0x432a, 0x43a1, { 0x8e, 0x25, 0x97, 0xe7, 0xd1, 0xef, 0x10, 0xf3, } }, { 0x6d646890, 0x3606, 0x461a, { 0x86, 0xab, 0x59, 0x8b, 0xb8, 0x4a, 0xce, 0x82 } } },
  1409. /* 006 */ { "W10\000Windows10\000", 25, 6, PWINGUID, { 0x73111121, 0x5638, 0x40f6, { 0xbc, 0x11, 0xf1, 0xd7, 0xb0, 0xd6, 0x43, 0x00, } }, { 0x58e2134f, 0x8e11, 0x4d17, { 0x9c, 0xb2, 0x91, 0x06, 0x9c, 0x15, 0x11, 0x48 } } },
  1410. /* 007 */ { "W10C\000Windows10C\000", 25, 6, PWINGUID, { 0x58e97c99, 0xf377, 0x4ef1, { 0x81, 0xd5, 0x4a, 0xd5, 0x52, 0x2b, 0x5f, 0xd8, } }, { 0xe1c51358, 0xfe3e, 0x4203, { 0xa4, 0xa2, 0x3b, 0x6b, 0x20, 0xc9, 0x73, 0x4e } } },
  1411. /* 008 */ { "2008" "\0" "2008A\000", 5, 4, PWINGUID, { 0xddfa9f7c, 0xf09e, 0x40b9, { 0x8c, 0x1a, 0xbe, 0x87, 0x7a, 0x9a, 0x7f, 0x4b, } }, { 0x33e156e4, 0xb76f, 0x4a52, { 0x9f, 0x91, 0xf6, 0x41, 0xdd, 0x95, 0xac, 0x48 } } },
  1412. /* 009 */ { "2008B\000", 5, 4, PWINGUID, { 0xc1af4d90, 0xd1bc, 0x44ca, { 0x85, 0xd4, 0x00, 0x3b, 0xa3, 0x3d, 0xb3, 0xb9, } }, { 0x8fe53387, 0x3087, 0x4447, { 0x89, 0x85, 0xf7, 0x51, 0x32, 0x21, 0x5a, 0xc9 } } },
  1413. /* 010 */ { "2008C\000", 5, 4, PWINGUID, { 0x68b6e220, 0xcf09, 0x466b, { 0x92, 0xd3, 0x45, 0xcd, 0x96, 0x4b, 0x95, 0x09, } }, { 0x8a21fdf3, 0xcbc5, 0x44eb, { 0x83, 0xf3, 0xfe, 0x28, 0x4e, 0x66, 0x80, 0xa7 } } },
  1414. /* 011 */ { "2008R2" "\0" "2008R2A\000", 5, 4, PWINGUID, { 0xa78b8bd9, 0x8017, 0x4df5, { 0xb8, 0x6a, 0x09, 0xf7, 0x56, 0xaf, 0xfa, 0x7c, } }, { 0x0fc6ccaf, 0xff0e, 0x4fae, { 0x9d, 0x08, 0x43, 0x70, 0x78, 0x5b, 0xf7, 0xed } } },
  1415. /* 012 */ { "2008R2B\000", 5, 4, PWINGUID, { 0x620e2b3d, 0x09e7, 0x42fd, { 0x80, 0x2a, 0x17, 0xa1, 0x36, 0x52, 0xfe, 0x7a, } }, { 0xca87f5b6, 0xcd46, 0x40c0, { 0xb0, 0x6d, 0x8e, 0xcd, 0x57, 0xa4, 0x37, 0x3f } } },
  1416. /* 013 */ { "2008R2C\000", 5, 4, PWINGUID, { 0x7482e61b, 0xc589, 0x4b7f, { 0x8e, 0xcc, 0x46, 0xd4, 0x55, 0xac, 0x3b, 0x87, } }, { 0xb2ca2689, 0xa9a8, 0x42d7, { 0x93, 0x8d, 0xcf, 0x8e, 0x9f, 0x20, 0x19, 0x58 } } },
  1417. /* 014 */ { "2012\000", 5, 5, PWINGUID, { 0xf0f5ec41, 0x0d55, 0x4732, { 0xaf, 0x02, 0x44, 0x0a, 0x44, 0xa3, 0xcf, 0x0f, } }, { 0x8665cb71, 0x468c, 0x4aa3, { 0xa3, 0x37, 0xcb, 0x9b, 0xc9, 0xd5, 0xea, 0xac } } },
  1418. /* 015 */ { "2012R2\000" "12R2\000", 5, 6, PWINGUID, { 0x00091344, 0x1ea4, 0x4f37, { 0xb7, 0x89, 0x01, 0x75, 0x0b, 0xa6, 0x98, 0x8c, } }, { 0x8456EFD3, 0x0C04, 0x4089, { 0x87, 0x40, 0x5b, 0x72, 0x38, 0x53, 0x5a, 0x65 } } },
  1419. /* 016 */ { "Office2010\000O14\000", 5, 4, POFFICE2010GUID, { 0x6f327760, 0x8c5c, 0x417c, { 0x9b, 0x61, 0x83, 0x6a, 0x98, 0x28, 0x7e, 0x0c, } }, { 0xe85af946, 0x2e25, 0x47b7, { 0x83, 0xe1, 0xbe, 0xbc, 0xeb, 0xea, 0xc6, 0x11 } } },
  1420. /* 017 */ { "Office2013\000O15\000", 5, 6, POFFICE2013GUID, { 0xb322da9c, 0xa2e2, 0x4058, { 0x9e, 0x4e, 0xf5, 0x9a, 0x69, 0x70, 0xbd, 0x69, } }, { 0xe6a6f1bf, 0x9d40, 0x40c3, { 0xaa, 0x9f, 0xc7, 0x7b, 0xa2, 0x15, 0x78, 0xc0 } } },
  1421. /* 018 */ { "Office2013V5\000", 5, 5, POFFICE2013GUID, { 0xb322da9c, 0xa2e2, 0x4058, { 0x9e, 0x4e, 0xf5, 0x9a, 0x69, 0x70, 0xbd, 0x69, } }, { 0xe6a6f1bf, 0x9d40, 0x40c3, { 0xaa, 0x9f, 0xc7, 0x7b, 0xa2, 0x15, 0x78, 0xc0 } } },
  1422. /* 019 */ { "Office2016\000" "O16\000", 5, 6, POFFICE2013GUID, { 0xd450596f, 0x894d, 0x49e0, { 0x96, 0x6a, 0xfd, 0x39, 0xed, 0x4c, 0x4c, 0x64, } }, { 0x85b5f61b, 0x320b, 0x4be3, { 0x81, 0x4a, 0xb7, 0x6b, 0x2b, 0xfa, 0xfc, 0x82 } } },
  1423. /* 020 */ { NULL, 0, 0, NULL, { 0, 0, 0, { 0, 0, 0, 0, 0, 0, 0, 0 } }, { 0, 0, 0, { 0, 0, 0, 0, 0, 0, 0, 0 } } }
  1424. };
  1425. typedef struct
  1426. {
  1427. const char* first[16];
  1428. const char* second[16];
  1429. const char* tld[22];
  1430. } DnsNames;
  1431. // Some names for the DNS name random generator
  1432. static DnsNames ClientDnsNames =
  1433. {
  1434. { "www", "ftp", "kms", "hack-me", "smtp", "ns1", "mx1", "ns1", "pop3", "imap", "mail", "dns", "headquarter", "we-love", "_vlmcs._tcp", "ceo-laptop" },
  1435. { ".microsoft", ".apple", ".amazon", ".samsung", ".adobe", ".google", ".yahoo", ".facebook", ".ubuntu", ".oracle", ".borland", ".htc", ".acer", ".windows", ".linux", ".sony" },
  1436. { ".com", ".net", ".org", ".cn", ".co.uk", ".de", ".com.tw", ".us", ".fr", ".it", ".me", ".info", ".biz", ".co.jp", ".ua", ".at", ".es", ".pro", ".by", ".ru", ".pl", ".kr" }
  1437. };
  1438. // This is the one, we are actually using. We use Vista, if user selects nothing
  1439. LicensePack ActiveLicensePack;
  1440. // Request Count Control Variables
  1441. static int RequestsToGo = 1;
  1442. static BOOL firstRequestSent = FALSE;
  1443. static void string2UuidOrExit(const char *const restrict input, GUID *const restrict guid)
  1444. {
  1445. if (strlen(input) != GUID_STRING_LENGTH || !string2Uuid(input, guid))
  1446. {
  1447. errorout("Fatal: Command line contains an invalid GUID.\n");
  1448. exit(!0);
  1449. }
  1450. }
  1451. #ifndef NO_HELP
  1452. __noreturn static void clientUsage(const char* const programName)
  1453. {
  1454. errorout(
  1455. "vlmcs %s \n\n"
  1456. # ifndef NO_DNS
  1457. "Usage: %s [options] [ <host>[:<port>] | .<domain> | - ] [options]\n\n"
  1458. # else // DNS
  1459. "Usage: %s [options] [<host>[:<port>]] [options]\n\n"
  1460. # endif // DNS
  1461. "Options:\n\n"
  1462. " -v Be verbose\n"
  1463. " -l <app>\n"
  1464. " -4 Force V4 protocol\n"
  1465. " -5 Force V5 protocol\n"
  1466. " -6 Force V6 protocol\n"
  1467. # ifndef USE_MSRPC
  1468. " -i <IpVersion> Use IP protocol (4 or 6)\n"
  1469. # endif // USE_MSRPC
  1470. " -e Show some valid examples\n"
  1471. " -x Show valid Apps\n"
  1472. " -d no DNS names, use Netbios names (no effect if -w is used)\n\n"
  1473. "Advanced options:\n\n"
  1474. " -a <AppGUID> Use custom Application GUID\n"
  1475. " -s <ActGUID> Use custom Activation Configuration GUID\n"
  1476. " -k <KmsGUID> Use custom KMS GUID\n"
  1477. " -c <ClientGUID> Use custom Client GUID. Default: Use random\n"
  1478. " -o <PreviousClientGUID> Use custom Prevoius Client GUID. Default: ZeroGUID\n"
  1479. " -w <Workstation> Use custom workstation name. Default: Use random\n"
  1480. " -r <RequiredClientCount> Fake required clients\n"
  1481. " -n <Requests> Fixed # of requests (Default: Enough to charge)\n"
  1482. " -m Pretend to be a virtual machine\n"
  1483. " -G <file> Get ePID/HwId data and write to <file>. Can't be used with -l, -4, -5, -6, -a, -s, -k, -r and -n\n"
  1484. # ifndef USE_MSRPC
  1485. " -T Use a new TCP connection for each request.\n"
  1486. " -N <0|1> disable or enable NDR64. Default: 1\n"
  1487. " -B <0|1> disable or enable RPC bind time feature negotiation. Default: 1\n"
  1488. # endif // USE_MSRPC
  1489. " -t <LicenseStatus> Use specfic license status (0 <= T <= 6)\n"
  1490. " -g <BindingExpiration> Use a specfic binding expiration time in minutes. Default 43200\n"
  1491. # ifndef NO_DNS
  1492. " -P Ignore priority and weight in DNS SRV records\n"
  1493. # endif // NO_DNS
  1494. # ifndef USE_MSRPC
  1495. " -p Don't use multiplexed RPC bind\n"
  1496. # endif // USE_MSRPC
  1497. "\n"
  1498. "<port>:\t\tTCP port name of the KMS to use. Default 1688.\n"
  1499. "<host>:\t\thost name of the KMS to use. Default 127.0.0.1\n"
  1500. # ifndef NO_DNS
  1501. ".<domain>:\tfind KMS server in <domain> via DNS\n"
  1502. # endif // NO_DNS
  1503. "<app>:\t\t(Type %s -x to see a list of valid apps)\n\n",
  1504. Version, programName, programName
  1505. );
  1506. exit(!0);
  1507. }
  1508. __pure static int getLineWidth(void)
  1509. {
  1510. #ifdef TERMINAL_FIXED_WIDTH // For Toolchains that to not have winsize
  1511. return TERMINAL_FIXED_WIDTH;
  1512. #else // Can determine width of terminal
  1513. #ifndef _WIN32
  1514. struct winsize w;
  1515. if(ioctl(STDOUT_FILENO, TIOCGWINSZ, &w))
  1516. {
  1517. return 80; // Return this if stdout is not a tty
  1518. }
  1519. return w.ws_col;
  1520. #else // _WIN32
  1521. CONSOLE_SCREEN_BUFFER_INFO csbiInfo;
  1522. HANDLE hStdout = GetStdHandle(STD_OUTPUT_HANDLE);
  1523. if (!GetConsoleScreenBufferInfo(hStdout, &csbiInfo))
  1524. {
  1525. return 80; // Return this if stdout is not a Console
  1526. }
  1527. return csbiInfo.srWindow.Right - csbiInfo.srWindow.Left;
  1528. #endif // WIN32
  1529. #endif // Can determine width of terminal
  1530. }
  1531. __noreturn static void showProducts(PRINTFUNC p)
  1532. {
  1533. int cols = getLineWidth();
  1534. int itemsPerLine;
  1535. uint8_t i;
  1536. p(
  1537. "The following "
  1538. #if !defined(NO_EXTENDED_PRODUCT_LIST) && !defined(NO_BASIC_PRODUCT_LIST)
  1539. "aliases "
  1540. #else
  1541. "names "
  1542. #endif
  1543. "can be used with -l:\n\n"
  1544. );
  1545. const LicensePack* lp;
  1546. itemsPerLine = cols / 20;
  1547. if (!itemsPerLine) itemsPerLine = 1;
  1548. for (i = 1, lp = LicensePackList; lp->names; lp++)
  1549. {
  1550. const char* name;
  1551. for (name = lp->names; *name; name += strlen(name) + 1, i++)
  1552. {
  1553. p("%-20s", name);
  1554. if (!(i % itemsPerLine)) p("\n");
  1555. }
  1556. }
  1557. p("\n\n");
  1558. #if !defined(NO_EXTENDED_PRODUCT_LIST) && !defined(NO_BASIC_PRODUCT_LIST)
  1559. const KmsIdList* currentProduct;
  1560. uint_fast8_t longestString = 0;
  1561. uint8_t k, items = getExtendedProductListSize();
  1562. p("You may also use these product names or numbers:\n\n");
  1563. for (currentProduct = ExtendedProductList; currentProduct->name; currentProduct++)
  1564. {
  1565. uint_fast8_t len = strlen(currentProduct->name);
  1566. if (len > longestString)
  1567. longestString = len;
  1568. }
  1569. itemsPerLine = cols / (longestString + 10);
  1570. if (!itemsPerLine) itemsPerLine = 1;
  1571. uint8_t lines = items / itemsPerLine;
  1572. if (items % itemsPerLine) lines++;
  1573. for (i = 0; i < lines; i++)
  1574. {
  1575. for (k = 0; k < itemsPerLine; k++)
  1576. {
  1577. uint8_t j;
  1578. uint8_t index = k * lines + i;
  1579. if (index >= items) break;
  1580. p("%3u = %s", index + 1, ExtendedProductList[index].name);
  1581. for (j = 0; j < longestString + 4 - strlen(ExtendedProductList[index].name); j++)
  1582. {
  1583. p(" ");
  1584. }
  1585. }
  1586. p("\n");
  1587. }
  1588. p("\n");
  1589. #endif // !defined(NO_EXTENDED_PRODUCT_LIST) && !defined(NO_BASIC_PRODUCT_LIST)
  1590. exit(0);
  1591. }
  1592. __noreturn static void examples(const char* const programName)
  1593. {
  1594. printf(
  1595. "\nRequest activation for Office2013 using V4 protocol from 192.168.1.5:1688\n"
  1596. "\t%s -l O15 -4 192.168.1.5\n"
  1597. "\t%s -l O15 -4 192.168.1.5:1688\n\n"
  1598. "Request activation for Windows Server 2012 using V4 protocol from localhost:1688\n"
  1599. "\t%s -4 -l Windows -k 8665cb71-468c-4aa3-a337-cb9bc9d5eaac\n"
  1600. "\t%s -4 -l 2012\n"
  1601. "\t%s -4 -l 2012 [::1]:1688\n"
  1602. "\t%s -4 -l 12 127.0.0.2:1688\n\n"
  1603. "Send 100,000 requests to localhost:1688\n"
  1604. "\t%s -n 100000 -l Office2010\n\n"
  1605. "Request Activation for Windows 8 from 10.0.0.1:4711 and pretend to be Steve Ballmer\n"
  1606. "\t%s -l Windows8 -w steveb1.redmond.microsoft.com 10.0.0.1:4711\n\n",
  1607. programName, programName, programName, programName, programName, programName, programName, programName
  1608. );
  1609. exit(0);
  1610. }
  1611. #else // NO_HELP
  1612. __noreturn static void clientUsage(const char* const programName)
  1613. {
  1614. errorout("Incorrect parameter specified.\n");
  1615. exit(!0);
  1616. }
  1617. #endif // NO_HELP
  1618. static BOOL findLicensePackByName(const char* const name, LicensePack* const lp)
  1619. {
  1620. // Try to find a package in the short list first
  1621. LicensePack *licensePack;
  1622. for (licensePack = (LicensePack*)&LicensePackList; licensePack->names; licensePack ++)
  1623. {
  1624. const char *currentName;
  1625. for (currentName = licensePack->names; *currentName; currentName += strlen(currentName) + 1)
  1626. {
  1627. if (!strcasecmp(name, currentName))
  1628. {
  1629. *lp = *licensePack;
  1630. return TRUE;
  1631. }
  1632. }
  1633. }
  1634. #if defined(NO_BASIC_PRODUCT_LIST) || defined(NO_EXTENDED_PRODUCT_LIST)
  1635. return FALSE;
  1636. #else // Both Lists are available
  1637. // search extended product list
  1638. uint8_t items = getExtendedProductListSize();
  1639. unsigned int index;
  1640. if (stringToInt(name, 1, items, &index))
  1641. {
  1642. index--;
  1643. }
  1644. else
  1645. {
  1646. for (index = 0; index < items; index++)
  1647. {
  1648. if (!strcasecmp(ExtendedProductList[index].name, name)) break;
  1649. }
  1650. if (index >= items) return FALSE;
  1651. }
  1652. lp->AppID = &AppList[ExtendedProductList[index].AppIndex].guid;
  1653. lp->KMSID = ProductList[ExtendedProductList[index].KmsIndex].guid;
  1654. lp->ActID = ExtendedProductList[index].guid;
  1655. lp->N_Policy = ProductList[ExtendedProductList[index].KmsIndex].KMS_PARAM_REQUIREDCOUNT;
  1656. lp->kmsVersionMajor = ProductList[ExtendedProductList[index].KmsIndex].KMS_PARAM_MAJOR;
  1657. return TRUE;
  1658. #endif // Both Lists are available
  1659. }
  1660. static const char* const client_optstring = "+N:B:i:l:a:s:k:c:w:r:n:t:g:G:o:pPTv456mexd";
  1661. //First pass. We handle only "-l". Since -a -k -s -4 -5 and -6 are exceptions to -l, we process -l first
  1662. static void parseCommandLinePass1(const int argc, CARGV argv)
  1663. {
  1664. int o;
  1665. optReset();
  1666. for (opterr = 0; ( o = getopt(argc, (char* const*)argv, client_optstring) ) > 0; ) switch (o)
  1667. {
  1668. case 'l': // Set "License Pack" and protocol version (e.g. Windows8, Office2013v5, ...)
  1669. if (!findLicensePackByName(optarg, &ActiveLicensePack))
  1670. {
  1671. errorout("Invalid client application. \"%s\" is not valid for -l.\n\n", optarg);
  1672. #ifndef NO_HELP
  1673. showProducts(&errorout);
  1674. #endif // !NO_HELP
  1675. }
  1676. break;
  1677. default:
  1678. break;
  1679. }
  1680. }
  1681. // Second Pass. Handle all options except "-l"
  1682. static void parseCommandLinePass2(const char *const programName, const int argc, CARGV argv)
  1683. {
  1684. int o;
  1685. optReset();
  1686. for (opterr = 0; ( o = getopt(argc, (char* const*)argv, client_optstring) ) > 0; ) switch (o)
  1687. {
  1688. #ifndef NO_HELP
  1689. case 'e': // Show examples
  1690. examples(programName);
  1691. break;
  1692. case 'x': // Show Apps
  1693. showProducts(&printf);
  1694. break;
  1695. #endif // NO_HELP
  1696. # ifndef NO_DNS
  1697. case 'P':
  1698. NoSrvRecordPriority = TRUE;
  1699. break;
  1700. # endif // NO_DNS
  1701. case 'G':
  1702. incompatibleOptions |= VLMCS_OPTION_GRAB_INI;
  1703. fn_ini_client = optarg;
  1704. break;
  1705. # ifndef USE_MSRPC
  1706. case 'N':
  1707. if (!getArgumentBool(&UseRpcNDR64, optarg)) clientUsage(programName);
  1708. break;
  1709. case 'B':
  1710. if (!getArgumentBool(&UseRpcBTFN, optarg)) clientUsage(programName);
  1711. break;
  1712. case 'i':
  1713. switch(getOptionArgumentInt(o, 4, 6))
  1714. {
  1715. case 4:
  1716. AddressFamily = AF_INET;
  1717. break;
  1718. case 6:
  1719. AddressFamily = AF_INET6;
  1720. break;
  1721. default:
  1722. errorout("IPv5 does not exist.\n");
  1723. exit(!0);
  1724. break;
  1725. }
  1726. break;
  1727. case 'p': // Multiplexed RPC
  1728. UseMultiplexedRpc = FALSE;
  1729. break;
  1730. # endif // USE_MSRPC
  1731. case 'n': // Fixed number of Requests (regardless, whether they are required)
  1732. incompatibleOptions |= VLMCS_OPTION_NO_GRAB_INI;
  1733. FixedRequests = getOptionArgumentInt(o, 1, INT_MAX);
  1734. break;
  1735. case 'r': // Fake minimum required client count
  1736. incompatibleOptions |= VLMCS_OPTION_NO_GRAB_INI;
  1737. ActiveLicensePack.N_Policy = getOptionArgumentInt(o, 1, INT_MAX);
  1738. break;
  1739. case 'c': // use a specific client GUID
  1740. // If using a constant Client ID, send only one request unless /N= explicitly specified
  1741. if (!FixedRequests) FixedRequests = 1;
  1742. CMID = optarg;
  1743. break;
  1744. case 'o': // use a specific previous client GUID
  1745. CMID_prev = optarg;
  1746. break;
  1747. case 'a': // Set specific App Id
  1748. incompatibleOptions |= VLMCS_OPTION_NO_GRAB_INI;
  1749. ActiveLicensePack.AppID = (GUID*)vlmcsd_malloc(sizeof(GUID));
  1750. string2UuidOrExit(optarg, (GUID*)ActiveLicensePack.AppID);
  1751. break;
  1752. case 'g': // Set custom "grace" time in minutes (default 30 days)
  1753. BindingExpiration = getOptionArgumentInt(o, 0, INT_MAX);
  1754. break;
  1755. case 's': // Set specfic SKU ID
  1756. incompatibleOptions |= VLMCS_OPTION_NO_GRAB_INI;
  1757. string2UuidOrExit(optarg, &ActiveLicensePack.ActID);
  1758. break;
  1759. case 'k': // Set specific KMS ID
  1760. incompatibleOptions |= VLMCS_OPTION_NO_GRAB_INI;
  1761. string2UuidOrExit(optarg, &ActiveLicensePack.KMSID);
  1762. break;
  1763. case '4': // Force V4 protocol
  1764. case '5': // Force V5 protocol
  1765. case '6': // Force V5 protocol
  1766. incompatibleOptions |= VLMCS_OPTION_NO_GRAB_INI;
  1767. ActiveLicensePack.kmsVersionMajor = o - 0x30;
  1768. break;
  1769. case 'd': // Don't use DNS names
  1770. dnsnames = FALSE;
  1771. break;
  1772. case 'v': // Be verbose
  1773. verbose = TRUE;
  1774. break;
  1775. case 'm': // Pretend to be a virtual machine
  1776. VMInfo = TRUE;
  1777. break;
  1778. case 'w': // WorkstationName (max. 63 chars)
  1779. WorkstationName = optarg;
  1780. if (strlen(WorkstationName) > 63)
  1781. {
  1782. errorout("\007WARNING! Truncating Workstation name to 63 characters (%s).\n", WorkstationName);
  1783. }
  1784. break;
  1785. case 't':
  1786. LicenseStatus = getOptionArgumentInt(o, 0, 6) & 0xff;
  1787. break;
  1788. # ifndef USE_MSRPC
  1789. case 'T':
  1790. ReconnectForEachRequest = TRUE;
  1791. break;
  1792. # endif // USE_MSRPC
  1793. case 'l':
  1794. incompatibleOptions |= VLMCS_OPTION_NO_GRAB_INI;
  1795. break;
  1796. default:
  1797. clientUsage(programName);
  1798. }
  1799. if ((incompatibleOptions & (VLMCS_OPTION_NO_GRAB_INI | VLMCS_OPTION_GRAB_INI)) == (VLMCS_OPTION_NO_GRAB_INI | VLMCS_OPTION_GRAB_INI))
  1800. clientUsage(programName);
  1801. }
  1802. /*
  1803. * Compares 2 GUIDs where one is host-endian and the other is little-endian (network byte order)
  1804. */
  1805. int_fast8_t IsEqualGuidLEHE(const GUID* const guid1, const GUID* const guid2)
  1806. {
  1807. GUID tempGuid;
  1808. LEGUID(&tempGuid, guid2);
  1809. return IsEqualGUID(guid1, &tempGuid);
  1810. }
  1811. #ifndef USE_MSRPC
  1812. static void checkRpcLevel(const REQUEST* request, RESPONSE* response)
  1813. {
  1814. if (!RpcFlags.HasNDR32)
  1815. errorout("\nWARNING: Server's RPC protocol does not support NDR32.\n");
  1816. if (UseRpcBTFN && UseRpcNDR64 && RpcFlags.HasNDR64 && !RpcFlags.HasBTFN)
  1817. errorout("\nWARNING: Server's RPC protocol has NDR64 but no BTFN.\n");
  1818. if (!IsEqualGuidLEHE(&request->KMSID, &ProductList[15].guid) && UseRpcBTFN && !RpcFlags.HasBTFN)
  1819. errorout("\nWARNING: A server with pre-Vista RPC activated a product other than Office 2010.\n");
  1820. }
  1821. #endif // USE_MSRPC
  1822. static void displayResponse(const RESPONSE_RESULT result, const REQUEST* request, RESPONSE* response, BYTE *hwid)
  1823. {
  1824. fflush(stdout);
  1825. if (!result.RpcOK) errorout("\n\007ERROR: Non-Zero RPC result code.\n");
  1826. if (!result.DecryptSuccess) errorout("\n\007ERROR: Decryption of V5/V6 response failed.\n");
  1827. if (!result.IVsOK) errorout("\n\007ERROR: AES CBC initialization vectors (IVs) of request and response do not match.\n");
  1828. if (!result.PidLengthOK) errorout("\n\007ERROR: The length of the PID is not valid.\n");
  1829. if (!result.HashOK) errorout("\n\007ERROR: Computed hash does not match hash in response.\n");
  1830. if (!result.ClientMachineIDOK) errorout("\n\007ERROR: Client machine GUIDs of request and response do not match.\n");
  1831. if (!result.TimeStampOK) errorout("\n\007ERROR: Time stamps of request and response do not match.\n");
  1832. if (!result.VersionOK) errorout("\n\007ERROR: Protocol versions of request and response do not match.\n");
  1833. if (!result.HmacSha256OK) errorout("\n\007ERROR: Keyed-Hash Message Authentication Code (HMAC) is incorrect.\n");
  1834. if (!result.IVnotSuspicious) errorout("\nWARNING: Response uses an IV following KMSv5 rules in KMSv6 protocol.\n");
  1835. if (result.effectiveResponseSize != result.correctResponseSize)
  1836. {
  1837. errorout("\n\007WARNING: Size of RPC payload (KMS Message) should be %u but is %u.", result.correctResponseSize, result.effectiveResponseSize);
  1838. }
  1839. # ifndef USE_MSRPC
  1840. checkRpcLevel(request, response);
  1841. # endif // USE_MSRPC
  1842. if (!result.DecryptSuccess) return; // Makes no sense to display anything
  1843. char ePID[3 * PID_BUFFER_SIZE];
  1844. if (!ucs2_to_utf8(response->KmsPID, ePID, PID_BUFFER_SIZE, 3 * PID_BUFFER_SIZE))
  1845. {
  1846. memset(ePID + 3 * PID_BUFFER_SIZE - 3, 0, 3);
  1847. }
  1848. // Read KMSPID from Response
  1849. if (!verbose)
  1850. {
  1851. printf(" -> %s", ePID);
  1852. if (LE16(response->MajorVer) > 5)
  1853. {
  1854. # ifndef _WIN32
  1855. printf(" (%016llX)", (unsigned long long)BE64(*(uint64_t*)hwid));
  1856. # else // _WIN32
  1857. printf(" (%016I64X)", (unsigned long long)BE64(*(uint64_t*)hwid));
  1858. # endif // _WIN32
  1859. }
  1860. printf("\n");
  1861. }
  1862. else
  1863. {
  1864. printf(
  1865. "\n\nResponse from KMS server\n========================\n\n"
  1866. "Size of KMS Response : %u (0x%x)\n", result.effectiveResponseSize, result.effectiveResponseSize
  1867. );
  1868. logResponseVerbose(ePID, hwid, response, &printf);
  1869. printf("\n");
  1870. }
  1871. }
  1872. static void connectRpc(RpcCtx *s)
  1873. {
  1874. # ifdef NO_DNS
  1875. *s = connectToAddress(RemoteAddr, AddressFamily, FALSE);
  1876. if (*s == INVALID_RPCCTX)
  1877. {
  1878. errorout("Fatal: Could not connect to %s\n", RemoteAddr);
  1879. exit(!0);
  1880. }
  1881. if (verbose)
  1882. printf("\nPerforming RPC bind ...\n");
  1883. if (rpcBindClient(*s, verbose))
  1884. {
  1885. errorout("Fatal: Could not bind RPC\n");
  1886. exit(!0);
  1887. }
  1888. if (verbose) printf("... successful\n");
  1889. # else // DNS
  1890. static kms_server_dns_ptr* serverlist = NULL;
  1891. static int numServers = 0;
  1892. //static int_fast8_t ServerListAlreadyPrinted = FALSE;
  1893. int i;
  1894. if (!strcmp(RemoteAddr, "-") || *RemoteAddr == '.') // Get KMS server via DNS SRV record
  1895. {
  1896. if (!serverlist)
  1897. numServers = getKmsServerList(&serverlist, RemoteAddr);
  1898. if (numServers < 1)
  1899. {
  1900. errorout("Fatal: No KMS servers found\n");
  1901. exit(!0);
  1902. }
  1903. if (!NoSrvRecordPriority) sortSrvRecords(serverlist, numServers);
  1904. if (verbose /*&& !ServerListAlreadyPrinted*/)
  1905. {
  1906. for (i = 0; i < numServers; i++)
  1907. {
  1908. printf(
  1909. "Found %-40s (priority: %hu, weight: %hu, randomized weight: %i)\n",
  1910. serverlist[i]->serverName,
  1911. serverlist[i]->priority, serverlist[i]->weight,
  1912. NoSrvRecordPriority ? 0 : serverlist[i]->random_weight
  1913. );
  1914. }
  1915. printf("\n");
  1916. //ServerListAlreadyPrinted = TRUE;
  1917. }
  1918. }
  1919. else // Just use the server supplied on the command line
  1920. {
  1921. if (!serverlist)
  1922. {
  1923. serverlist = (kms_server_dns_ptr*)vlmcsd_malloc(sizeof(kms_server_dns_ptr));
  1924. *serverlist = (kms_server_dns_ptr)vlmcsd_malloc(sizeof(kms_server_dns_t));
  1925. numServers = 1;
  1926. strncpy((*serverlist)->serverName, RemoteAddr, sizeof((*serverlist)->serverName));
  1927. }
  1928. }
  1929. for (i = 0; i < numServers; i++)
  1930. {
  1931. *s = connectToAddress(serverlist[i]->serverName, AddressFamily, (*RemoteAddr == '.' || *RemoteAddr == '-'));
  1932. if (*s == INVALID_RPCCTX) continue;
  1933. if (verbose)
  1934. printf("\nPerforming RPC bind ...\n");
  1935. if (rpcBindClient(*s, verbose))
  1936. {
  1937. errorout("Warning: Could not bind RPC\n");
  1938. continue;
  1939. }
  1940. if (verbose) printf("... successful\n");
  1941. return;
  1942. }
  1943. errorout("Fatal: Could not connect to any KMS server\n");
  1944. exit(!0);
  1945. # endif // DNS
  1946. }
  1947. static int SendActivationRequest(const RpcCtx sock, RESPONSE *baseResponse, REQUEST *baseRequest, RESPONSE_RESULT *result, BYTE *const hwid)
  1948. {
  1949. size_t requestSize, responseSize;
  1950. BYTE *request, *response;
  1951. int status;
  1952. result->mask = 0;
  1953. if (LE16(baseRequest->MajorVer) == 4)
  1954. request = CreateRequestV4(&requestSize, baseRequest);
  1955. else
  1956. request = CreateRequestV6(&requestSize, baseRequest);
  1957. if (!(status = rpcSendRequest(sock, request, requestSize, &response, &responseSize)))
  1958. {
  1959. if (LE16(((RESPONSE*)(response))->MajorVer) == 4)
  1960. {
  1961. RESPONSE_V4 response_v4;
  1962. *result = DecryptResponseV4(&response_v4, responseSize, response, request);
  1963. memcpy(baseResponse, &response_v4.ResponseBase, sizeof(RESPONSE));
  1964. }
  1965. else
  1966. {
  1967. RESPONSE_V6 response_v6;
  1968. *result = DecryptResponseV6(&response_v6, responseSize, response, request, hwid);
  1969. memcpy(baseResponse, &response_v6.ResponseBase, sizeof(RESPONSE));
  1970. }
  1971. result->RpcOK = TRUE;
  1972. }
  1973. if (response) free(response);
  1974. free(request);
  1975. return status;
  1976. }
  1977. static int sendRequest(RpcCtx *const s, REQUEST *const request, RESPONSE *const response, hwid_t hwid, RESPONSE_RESULT *const result)
  1978. {
  1979. CreateRequestBase(request);
  1980. if (*s == INVALID_RPCCTX )
  1981. connectRpc(s);
  1982. else
  1983. {
  1984. // Check for lame KMS emulators that close the socket after each request
  1985. int_fast8_t disconnected = isDisconnected(*s);
  1986. if (disconnected)
  1987. errorout("\nWarning: Server closed RPC connection (probably non-multitasked KMS emulator)\n");
  1988. if (ReconnectForEachRequest || disconnected)
  1989. {
  1990. closeRpc(*s);
  1991. connectRpc(s);
  1992. }
  1993. }
  1994. printf("Sending activation request (KMS V%u) ", ActiveLicensePack.kmsVersionMajor);
  1995. fflush(stdout);
  1996. return SendActivationRequest(*s, response, request, result, hwid);
  1997. }
  1998. static void displayRequestError(RpcCtx *const s, const int status, const int currentRequest, const int totalRequests)
  1999. {
  2000. errorout("\nError 0x%08X while sending request %u of %u\n", status, currentRequest, RequestsToGo + totalRequests);
  2001. switch(status)
  2002. {
  2003. case 0xC004F042: // not licensed
  2004. errorout("The server refused to activate the requested product\n");
  2005. break;
  2006. case 0x8007000D: // e.g. v6 protocol on a v5 server
  2007. errorout("The server didn't understand the request\n");
  2008. break;
  2009. case 1:
  2010. errorout("An RPC protocol error has occured\n");
  2011. closeRpc(*s);
  2012. connectRpc(s);
  2013. break;
  2014. default:
  2015. break;
  2016. }
  2017. }
  2018. static void newIniBackupFile(const char* const restrict fname)
  2019. {
  2020. FILE *restrict f = fopen(fname, "wb");
  2021. if (!f)
  2022. {
  2023. errorout("Fatal: Cannot create %s: %s\n", fname, strerror(errno));
  2024. exit(!0);
  2025. }
  2026. if (fclose(f))
  2027. {
  2028. errorout("Fatal: Cannot write to %s: %s\n", fname, strerror(errno));
  2029. unlink(fname);
  2030. exit(!0);
  2031. }
  2032. }
  2033. static void updateIniFile(iniFileEpidLines* const restrict lines)
  2034. {
  2035. int_fast8_t lineWritten[_countof(*lines)];
  2036. struct stat statbuf;
  2037. uint_fast8_t i;
  2038. int_fast8_t iniFileExistedBefore = TRUE;
  2039. unsigned int lineNumber;
  2040. memset(lineWritten, FALSE, sizeof(lineWritten));
  2041. char* restrict fn_bak = (char*)vlmcsd_malloc(strlen(fn_ini_client) + 2);
  2042. strcpy(fn_bak, fn_ini_client);
  2043. strcat(fn_bak, "~");
  2044. if (stat(fn_ini_client, &statbuf))
  2045. {
  2046. if (errno != ENOENT)
  2047. {
  2048. errorout("Fatal: %s: %s\n", fn_ini_client, strerror(errno));
  2049. exit(!0);
  2050. }
  2051. else
  2052. {
  2053. iniFileExistedBefore = FALSE;
  2054. newIniBackupFile(fn_bak);
  2055. }
  2056. }
  2057. else
  2058. {
  2059. unlink(fn_bak); // Required for Windows. Most Unix systems don't need it.
  2060. if (rename(fn_ini_client, fn_bak))
  2061. {
  2062. errorout("Fatal: Cannot create %s: %s\n", fn_bak, strerror(errno));
  2063. exit(!0);
  2064. }
  2065. }
  2066. printf("\n%s file %s\n", iniFileExistedBefore ? "Updating" : "Creating", fn_ini_client);
  2067. FILE *restrict in, *restrict out;
  2068. in = fopen(fn_bak, "rb");
  2069. if (!in)
  2070. {
  2071. errorout("Fatal: Cannot open %s: %s\n", fn_bak, strerror(errno));
  2072. exit(!0);
  2073. }
  2074. out = fopen(fn_ini_client, "wb");
  2075. if (!out)
  2076. {
  2077. errorout("Fatal: Cannot create %s: %s\n", fn_ini_client, strerror(errno));
  2078. exit(!0);
  2079. }
  2080. char sourceLine[256];
  2081. for (lineNumber = 1; fgets(sourceLine, sizeof(sourceLine), in); lineNumber++)
  2082. {
  2083. for (i = 0; i < _countof(*lines); i++)
  2084. {
  2085. if (*(*lines)[i] && !strncasecmp(sourceLine, (*lines)[i], GUID_STRING_LENGTH))
  2086. {
  2087. if (lineWritten[i]) break;
  2088. fprintf(out, "%s", (*lines)[i]);
  2089. printf("line %2i: %s", lineNumber, (*lines)[i]);
  2090. lineWritten[i] = TRUE;
  2091. break;
  2092. }
  2093. }
  2094. if (i >= _countof(*lines))
  2095. {
  2096. fprintf(out, "%s", sourceLine);
  2097. }
  2098. }
  2099. if (ferror(in))
  2100. {
  2101. errorout("Fatal: Cannot read from %s: %s\n", fn_bak, strerror(errno));
  2102. exit(!0);
  2103. }
  2104. fclose(in);
  2105. for (i = 0; i < _countof(*lines); i++)
  2106. {
  2107. if (!lineWritten[i] && *(*lines)[i])
  2108. {
  2109. fprintf(out, "%s", (*lines)[i]);
  2110. printf("line %2i: %s", lineNumber + i, (*lines)[i]);
  2111. }
  2112. }
  2113. if (fclose(out))
  2114. {
  2115. errorout("Fatal: Cannot write to %s: %s\n", fn_ini_client, strerror(errno));
  2116. exit(!0);
  2117. }
  2118. if (!iniFileExistedBefore) unlink(fn_bak);
  2119. free(fn_bak);
  2120. }
  2121. static void grabServerData()
  2122. {
  2123. RpcCtx s = INVALID_RPCCTX;
  2124. WORD MajorVer = 6;
  2125. iniFileEpidLines lines;
  2126. int_fast8_t Licenses[_countof(lines)] = { 0, 15, 14 };
  2127. uint_fast8_t i;
  2128. RESPONSE response;
  2129. RESPONSE_RESULT result;
  2130. REQUEST request;
  2131. hwid_t hwid;
  2132. int status;
  2133. size_t len;
  2134. for (i = 0; i < _countof(lines); i++) *lines[i] = 0;
  2135. for (i = 0; i < _countof(Licenses) && MajorVer > 3; i++)
  2136. {
  2137. ActiveLicensePack = LicensePackList[Licenses[i]];
  2138. ActiveLicensePack.kmsVersionMajor = MajorVer;
  2139. status = sendRequest(&s, &request, &response, hwid, &result);
  2140. printf("%-11s", ActiveLicensePack.names);
  2141. if (status)
  2142. {
  2143. displayRequestError(&s, status, i + 7 - MajorVer, 9 - MajorVer);
  2144. if (status == 1) break;
  2145. if ((status & 0xF0000000) == 0x80000000)
  2146. {
  2147. MajorVer--;
  2148. i--;
  2149. }
  2150. continue;
  2151. }
  2152. printf("%i of %i", (int)(i + 7 - MajorVer), (int)(9 - MajorVer));
  2153. displayResponse(result, &request, &response, hwid);
  2154. char guidBuffer[GUID_STRING_LENGTH + 1];
  2155. char ePID[3 * PID_BUFFER_SIZE];
  2156. uuid2StringLE(&request.AppID, guidBuffer);
  2157. if (!ucs2_to_utf8(response.KmsPID, ePID, PID_BUFFER_SIZE, 3 * PID_BUFFER_SIZE))
  2158. {
  2159. memset(ePID + 3 * PID_BUFFER_SIZE - 3, 0, 3);
  2160. }
  2161. snprintf(lines[i], sizeof(lines[0]), "%s = %s", guidBuffer, ePID);
  2162. if (response.MajorVer > 5)
  2163. {
  2164. len = strlen(lines[i]);
  2165. snprintf (lines[i] + len, sizeof(lines[0]) - len, "/ %02X %02X %02X %02X %02X %02X %02X %02X", hwid[0], hwid[1], hwid[2], hwid[3], hwid[4], hwid[5], hwid[6], hwid[7]);
  2166. }
  2167. len = strlen(lines[i]);
  2168. snprintf(lines[i] + len, sizeof(lines[0]) - len, "\n");
  2169. }
  2170. if (strcmp(fn_ini_client, "-"))
  2171. {
  2172. updateIniFile(&lines);
  2173. }
  2174. else
  2175. {
  2176. printf("\n");
  2177. for (i = 0; i < _countof(lines); i++) printf("%s", lines[i]);
  2178. }
  2179. }
  2180. int client_main(const int argc, CARGV argv)
  2181. {
  2182. #if defined(_WIN32) && !defined(USE_MSRPC)
  2183. // Windows Sockets must be initialized
  2184. WSADATA wsadata;
  2185. int error;
  2186. if ((error = WSAStartup(0x0202, &wsadata)))
  2187. {
  2188. printerrorf("Fatal: Could not initialize Windows sockets (Error: %d).\n", error);
  2189. return error;
  2190. }
  2191. #endif // _WIN32
  2192. #ifdef _NTSERVICE
  2193. // We are not a service
  2194. IsNTService = FALSE;
  2195. // Set console output page to UTF-8
  2196. // SetConsoleOutputCP(65001);
  2197. #endif // _NTSERVICE
  2198. randomNumberInit();
  2199. ActiveLicensePack = *LicensePackList; //first license is Windows Vista
  2200. parseCommandLinePass1(argc, argv);
  2201. int_fast8_t useDefaultHost = FALSE;
  2202. if (optind < argc)
  2203. RemoteAddr = argv[optind];
  2204. else
  2205. useDefaultHost = TRUE;
  2206. int hostportarg = optind;
  2207. if (optind < argc - 1)
  2208. {
  2209. parseCommandLinePass1(argc - hostportarg, argv + hostportarg);
  2210. if (optind < argc - hostportarg)
  2211. clientUsage(argv[0]);
  2212. }
  2213. parseCommandLinePass2(argv[0], argc, argv);
  2214. if (optind < argc - 1)
  2215. parseCommandLinePass2(argv[0], argc - hostportarg, argv + hostportarg);
  2216. if (useDefaultHost)
  2217. RemoteAddr = AddressFamily == AF_INET6 ? "::1" : "127.0.0.1";
  2218. if (fn_ini_client != NULL)
  2219. grabServerData();
  2220. else
  2221. {
  2222. int requests;
  2223. RpcCtx s = INVALID_RPCCTX;
  2224. for (requests = 0, RequestsToGo = ActiveLicensePack.N_Policy - 1; RequestsToGo; requests++)
  2225. {
  2226. RESPONSE response;
  2227. REQUEST request;
  2228. RESPONSE_RESULT result;
  2229. hwid_t hwid;
  2230. int status = sendRequest(&s, &request, &response, hwid, &result);
  2231. if (FixedRequests) RequestsToGo = FixedRequests - requests - 1;
  2232. if (status)
  2233. {
  2234. displayRequestError(&s, status, requests + 1, RequestsToGo + requests + 1);
  2235. if (!FixedRequests) RequestsToGo = 0;
  2236. }
  2237. else
  2238. {
  2239. if (!FixedRequests)
  2240. {
  2241. if (firstRequestSent && ActiveLicensePack.N_Policy - (int)response.Count >= RequestsToGo)
  2242. {
  2243. errorout("\nThe KMS server does not increment it's active clients. Aborting...\n");
  2244. RequestsToGo = 0;
  2245. }
  2246. else
  2247. {
  2248. RequestsToGo = ActiveLicensePack.N_Policy - response.Count;
  2249. if (RequestsToGo < 0) RequestsToGo = 0;
  2250. }
  2251. }
  2252. fflush(stderr);
  2253. printf("%i of %i ", requests + 1, RequestsToGo + requests + 1);
  2254. displayResponse(result, &request, &response, hwid);
  2255. firstRequestSent = TRUE;
  2256. }
  2257. }
  2258. }
  2259. return 0;
  2260. }
  2261. // Create Base KMS Client Request
  2262. static void CreateRequestBase(REQUEST *Request)
  2263. {
  2264. Request->MinorVer = LE16((WORD)kmsVersionMinor);
  2265. Request->MajorVer = LE16((WORD)ActiveLicensePack.kmsVersionMajor);
  2266. Request->VMInfo = LE32(VMInfo);
  2267. Request->LicenseStatus = LE32(LicenseStatus);
  2268. Request->BindingExpiration = LE32(BindingExpiration);
  2269. LEGUID(&Request->AppID, ActiveLicensePack.AppID);
  2270. LEGUID(&Request->ActID, &ActiveLicensePack.ActID);
  2271. LEGUID(&Request->KMSID, &ActiveLicensePack.KMSID);
  2272. getUnixTimeAsFileTime(&Request->ClientTime);
  2273. Request->N_Policy = LE32(ActiveLicensePack.N_Policy);
  2274. {
  2275. GUID tempGUID;
  2276. if (CMID)
  2277. {
  2278. string2UuidOrExit(CMID, &tempGUID);
  2279. LEGUID(&Request->CMID, &tempGUID);
  2280. }
  2281. else
  2282. {
  2283. get16RandomBytes(&Request->CMID);
  2284. // Set reserved UUID bits
  2285. Request->CMID.Data4[0] &= 0x3F;
  2286. Request->CMID.Data4[0] |= 0x80;
  2287. // Set UUID type 4 (random UUID)
  2288. Request->CMID.Data3 &= LE16(0xfff);
  2289. Request->CMID.Data3 |= LE16(0x4000);
  2290. }
  2291. if (CMID_prev)
  2292. {
  2293. string2UuidOrExit(CMID_prev, &tempGUID);
  2294. LEGUID(&Request->CMID_prev, &tempGUID);
  2295. }
  2296. else
  2297. {
  2298. memset(&Request->CMID_prev, 0, sizeof(Request->CMID_prev));
  2299. }
  2300. }
  2301. static const char alphanum[] = "0123456789" "ABCDEFGHIJKLMNOPQRSTUVWXYZ" /*"abcdefghijklmnopqrstuvwxyz" */;
  2302. if (WorkstationName)
  2303. {
  2304. utf8_to_ucs2(Request->WorkstationName, WorkstationName, WORKSTATION_NAME_BUFFER, WORKSTATION_NAME_BUFFER * 3);
  2305. }
  2306. else if (dnsnames)
  2307. {
  2308. int len, len2;
  2309. unsigned int index = rand() % _countof(ClientDnsNames.first);
  2310. len = utf8_to_ucs2(Request->WorkstationName, ClientDnsNames.first[index], WORKSTATION_NAME_BUFFER, WORKSTATION_NAME_BUFFER * 3);
  2311. index = rand() % _countof(ClientDnsNames.second);
  2312. len2 = utf8_to_ucs2(Request->WorkstationName + len, ClientDnsNames.second[index], WORKSTATION_NAME_BUFFER, WORKSTATION_NAME_BUFFER * 3);
  2313. index = rand() % _countof(ClientDnsNames.tld);
  2314. utf8_to_ucs2(Request->WorkstationName + len + len2, ClientDnsNames.tld[index], WORKSTATION_NAME_BUFFER, WORKSTATION_NAME_BUFFER * 3);
  2315. }
  2316. else
  2317. {
  2318. unsigned int size = (rand() % 14) + 1;
  2319. const unsigned char *dummy;
  2320. unsigned int i;
  2321. for (i = 0; i < size; i++)
  2322. {
  2323. Request->WorkstationName[i] = utf8_to_ucs2_char((unsigned char*)alphanum + (rand() % (sizeof(alphanum) - 1)), &dummy);
  2324. }
  2325. Request->WorkstationName[size] = 0;
  2326. }
  2327. //Show Details
  2328. if (verbose)
  2329. {
  2330. printf("\nRequest Parameters\n==================\n\n");
  2331. logRequestVerbose(Request, &printf);
  2332. printf("\n");
  2333. }
  2334. }
  2335. /* Multi-Call Binary for vlmcs and vlmcsd */
  2336. #ifndef CONFIG
  2337. #define CONFIG "config.h"
  2338. #endif // CONFIG
  2339. #include CONFIG
  2340. #if MULTI_CALL_BINARY < 1
  2341. #error "Please define MULTI_CALL_BINARY=1 when compiling this file."
  2342. #endif
  2343. #include <libgen.h>
  2344. #include <stdio.h>
  2345. #include "vlmcs.h"
  2346. #include "vlmcsd.h"
  2347. #include "types.h"
  2348. #include "shared_globals.h"
  2349. #include "output.h"
  2350. #if (defined(_WIN32) || defined(__CYGWIN__))
  2351. #define compare strcasecmp // Best for case-preserving (but otherwise case-insensitive) filesystems
  2352. #else // native Unix
  2353. #define compare strcmp // for case-sensitive filesystems
  2354. #endif // native Unix
  2355. int main(int argc, CARGV argv)
  2356. {
  2357. multi_argv = argv;
  2358. multi_argc = argc;
  2359. if (!compare(basename((char*)*argv), "vlmcsd"))
  2360. return server_main(argc, argv);
  2361. if (!compare(basename((char*)*argv), "vlmcs"))
  2362. return client_main(argc, argv);
  2363. #ifdef _WIN32
  2364. if (!compare(basename((char*)*argv), "vlmcsd.exe"))
  2365. return server_main(argc, argv);
  2366. if (!compare(basename((char*)*argv), "vlmcs.exe"))
  2367. return client_main(argc, argv);
  2368. #endif // _WIN32
  2369. if (argc > 1)
  2370. {
  2371. if (!strcmp((char*)argv[1],"vlmcsd"))
  2372. return server_main(argc - 1, argv + 1);
  2373. if (!strcmp((char*)argv[1],"vlmcs"))
  2374. return client_main(argc - 1, argv + 1);
  2375. }
  2376. errorout(
  2377. "vlmcsdmulti %s\n\n"
  2378. "Usage:\n"
  2379. "\t%s vlmcsd [<vlmcsd command line>]\n"
  2380. "\t%s vlmcs [<vlmcs command line>]\n\n",
  2381. Version, *argv, *argv
  2382. );
  2383. return !0;
  2384. }
  2385. #ifndef CONFIG
  2386. #define CONFIG "config.h"
  2387. #endif // CONFIG
  2388. #include CONFIG
  2389. #include "crypto.h"
  2390. #include "endian.h"
  2391. #include <stdint.h>
  2392. const BYTE AesKeyV4[] = {
  2393. 0x05, 0x3D, 0x83, 0x07, 0xF9, 0xE5, 0xF0, 0x88, 0xEB, 0x5E, 0xA6, 0x68, 0x6C, 0xF0, 0x37, 0xC7, 0xE4, 0xEF, 0xD2, 0xD6};
  2394. const BYTE AesKeyV5[] = {
  2395. 0xCD, 0x7E, 0x79, 0x6F, 0x2A, 0xB2, 0x5D, 0xCB, 0x55, 0xFF, 0xC8, 0xEF, 0x83, 0x64, 0xC4, 0x70 };
  2396. const BYTE AesKeyV6[] = {
  2397. 0xA9, 0x4A, 0x41, 0x95, 0xE2, 0x01, 0x43, 0x2D, 0x9B, 0xCB, 0x46, 0x04, 0x05, 0xD8, 0x4A, 0x21 };
  2398. static const BYTE SBox[] = {
  2399. 0x63, 0x7C, 0x77, 0x7B, 0xF2, 0x6B, 0x6F, 0xC5, 0x30, 0x01, 0x67, 0x2B,
  2400. 0xFE, 0xD7, 0xAB, 0x76, 0xCA, 0x82, 0xC9, 0x7D, 0xFA, 0x59, 0x47, 0xF0,
  2401. 0xAD, 0xD4, 0xA2, 0xAF, 0x9C, 0xA4, 0x72, 0xC0, 0xB7, 0xFD, 0x93, 0x26,
  2402. 0x36, 0x3F, 0xF7, 0xCC, 0x34, 0xA5, 0xE5, 0xF1, 0x71, 0xD8, 0x31, 0x15,
  2403. 0x04, 0xC7, 0x23, 0xC3, 0x18, 0x96, 0x05, 0x9A, 0x07, 0x12, 0x80, 0xE2,
  2404. 0xEB, 0x27, 0xB2, 0x75, 0x09, 0x83, 0x2C, 0x1A, 0x1B, 0x6E, 0x5A, 0xA0,
  2405. 0x52, 0x3B, 0xD6, 0xB3, 0x29, 0xE3, 0x2F, 0x84, 0x53, 0xD1, 0x00, 0xED,
  2406. 0x20, 0xFC, 0xB1, 0x5B, 0x6A, 0xCB, 0xBE, 0x39, 0x4A, 0x4C, 0x58, 0xCF,
  2407. 0xD0, 0xEF, 0xAA, 0xFB, 0x43, 0x4D, 0x33, 0x85, 0x45, 0xF9, 0x02, 0x7F,
  2408. 0x50, 0x3C, 0x9F, 0xA8, 0x51, 0xA3, 0x40, 0x8F, 0x92, 0x9D, 0x38, 0xF5,
  2409. 0xBC, 0xB6, 0xDA, 0x21, 0x10, 0xFF, 0xF3, 0xD2, 0xCD, 0x0C, 0x13, 0xEC,
  2410. 0x5F, 0x97, 0x44, 0x17, 0xC4, 0xA7, 0x7E, 0x3D, 0x64, 0x5D, 0x19, 0x73,
  2411. 0x60, 0x81, 0x4F, 0xDC, 0x22, 0x2A, 0x90, 0x88, 0x46, 0xEE, 0xB8, 0x14,
  2412. 0xDE, 0x5E, 0x0B, 0xDB, 0xE0, 0x32, 0x3A, 0x0A, 0x49, 0x06, 0x24, 0x5C,
  2413. 0xC2, 0xD3, 0xAC, 0x62, 0x91, 0x95, 0xE4, 0x79, 0xE7, 0xC8, 0x37, 0x6D,
  2414. 0x8D, 0xD5, 0x4E, 0xA9, 0x6C, 0x56, 0xF4, 0xEA, 0x65, 0x7A, 0xAE, 0x08,
  2415. 0xBA, 0x78, 0x25, 0x2E, 0x1C, 0xA6, 0xB4, 0xC6, 0xE8, 0xDD, 0x74, 0x1F,
  2416. 0x4B, 0xBD, 0x8B, 0x8A, 0x70, 0x3E, 0xB5, 0x66, 0x48, 0x03, 0xF6, 0x0E,
  2417. 0x61, 0x35, 0x57, 0xB9, 0x86, 0xC1, 0x1D, 0x9E, 0xE1, 0xF8, 0x98, 0x11,
  2418. 0x69, 0xD9, 0x8E, 0x94, 0x9B, 0x1E, 0x87, 0xE9, 0xCE, 0x55, 0x28, 0xDF,
  2419. 0x8C, 0xA1, 0x89, 0x0D, 0xBF, 0xE6, 0x42, 0x68, 0x41, 0x99, 0x2D, 0x0F,
  2420. 0xB0, 0x54, 0xBB, 0x16
  2421. };
  2422. void XorBlock(const BYTE *const in, const BYTE *out) // Ensure that this is always 32 bit aligned
  2423. {
  2424. /*UAA64( out, 0 ) ^= UAA64( in, 0 );
  2425. UAA64( out, 1 ) ^= UAA64( in, 1 );*/
  2426. uint_fast8_t i;
  2427. for (i = 0; i < AES_BLOCK_WORDS; i++)
  2428. {
  2429. ((DWORD*)out)[i] ^= ((DWORD*)in)[i];
  2430. }
  2431. }
  2432. #define AddRoundKey(d, rk) XorBlock((const BYTE *)rk, (const BYTE *)d)
  2433. #define Mul2(word) (((word & 0x7f7f7f7f) << 1) ^ (((word & 0x80808080) >> 7) * 0x1b))
  2434. #define Mul3(word) (Mul2(word) ^ word)
  2435. #define Mul4(word) (Mul2(Mul2(word)))
  2436. #define Mul8(word) (Mul2(Mul2(Mul2(word))))
  2437. #define Mul9(word) (Mul8(word) ^ word)
  2438. #define MulB(word) (Mul8(word) ^ Mul3(word))
  2439. #define MulD(word) (Mul8(word) ^ Mul4(word) ^ word)
  2440. #define MulE(word) (Mul8(word) ^ Mul4(word) ^ Mul2(word))
  2441. //32 bit Galois Multiplication (generates bigger code than Macros)
  2442. /*static DWORD Mul(DWORD x, DWORD y)
  2443. {
  2444. DWORD result = x, yTemp = y, log2;
  2445. if (!y) return 0;
  2446. for (log2 = 0; yTemp >>= 1; log2++ )
  2447. {
  2448. result = Mul2(result);
  2449. }
  2450. return result ^ Mul(x, y - (1 << log2));
  2451. }*/
  2452. void MixColumnsR(BYTE *restrict state)
  2453. {
  2454. uint_fast8_t i = 0;
  2455. for (; i < AES_BLOCK_WORDS; i++)
  2456. {
  2457. #if defined(_CRYPTO_OPENSSL) && defined(_OPENSSL_SOFTWARE) && defined(_USE_AES_FROM_OPENSSL) //Always byte swap regardless of endianess
  2458. DWORD word = BS32(((DWORD *) state)[i]);
  2459. ((DWORD *) state)[i] = BS32(MulE(word) ^ ROR32(MulB(word), 8) ^ ROR32(MulD(word), 16) ^ ROR32(Mul9(word), 24));
  2460. #else
  2461. DWORD word = LE32(((DWORD *) state)[i]);
  2462. ((DWORD *) state)[i] = LE32(MulE(word) ^ ROR32(MulB(word), 8) ^ ROR32(MulD(word), 16) ^ ROR32(Mul9(word), 24));
  2463. #endif
  2464. }
  2465. }
  2466. static DWORD SubDword(DWORD v)
  2467. {
  2468. BYTE *b = (BYTE *)&v;
  2469. uint_fast8_t i = 0;
  2470. for (; i < sizeof(DWORD); i++) b[i] = SBox[b[i]];
  2471. return v;
  2472. }
  2473. void AesInitKey(AesCtx *Ctx, const BYTE *Key, int_fast8_t IsV6, int RijndaelKeyBytes)
  2474. {
  2475. int RijndaelKeyDwords = RijndaelKeyBytes / sizeof(DWORD);
  2476. Ctx->rounds = (uint_fast8_t)(RijndaelKeyDwords + 6);
  2477. static const DWORD RCon[] = {
  2478. 0x00000000, 0x01000000, 0x02000000, 0x04000000, 0x08000000, 0x10000000,
  2479. 0x20000000, 0x40000000, 0x80000000, 0x1B000000, 0x36000000 };
  2480. uint_fast8_t i;
  2481. DWORD temp;
  2482. memcpy(Ctx->Key, Key, RijndaelKeyBytes);
  2483. for ( i = RijndaelKeyDwords; i < ( Ctx->rounds + 1 ) << 2; i++ )
  2484. {
  2485. temp = Ctx->Key[ i - 1 ];
  2486. if ( ( i % RijndaelKeyDwords ) == 0 )
  2487. temp = BE32( SubDword( ROR32( BE32(temp), 24) ) ^ RCon[ i / RijndaelKeyDwords ] );
  2488. Ctx->Key[ i ] = Ctx->Key[ i - RijndaelKeyDwords ] ^ temp;
  2489. }
  2490. if ( IsV6 )
  2491. {
  2492. BYTE *_p = (BYTE *)Ctx->Key;
  2493. _p[ 4 * 16 ] ^= 0x73;
  2494. _p[ 6 * 16 ] ^= 0x09;
  2495. _p[ 8 * 16 ] ^= 0xE4;
  2496. }
  2497. }
  2498. #if !defined(_CRYPTO_OPENSSL) || !defined(_USE_AES_FROM_OPENSSL) || defined(_OPENSSL_SOFTWARE)
  2499. static void SubBytes(BYTE *block)
  2500. {
  2501. uint_fast8_t i;
  2502. for (i = 0; i < AES_BLOCK_BYTES; i++)
  2503. block[i] = SBox[ block[i] ];
  2504. }
  2505. static void ShiftRows(BYTE *state)
  2506. {
  2507. BYTE bIn[AES_BLOCK_BYTES];
  2508. uint_fast8_t i;
  2509. memcpy(bIn, state, AES_BLOCK_BYTES);
  2510. for (i = 0; i < AES_BLOCK_BYTES; i++)
  2511. {
  2512. state[i] = bIn[(i + ((i & 3) << 2)) & 0xf];
  2513. }
  2514. };
  2515. static void MixColumns(BYTE *state)
  2516. {
  2517. uint_fast8_t i = 0;
  2518. for (; i < AES_BLOCK_WORDS; i++)
  2519. {
  2520. DWORD word = LE32(((DWORD *) state)[i]);
  2521. ((DWORD *) state)[i] = LE32(Mul2(word) ^ ROR32(Mul3(word), 8) ^ ROR32(word, 16) ^ ROR32(word, 24));
  2522. }
  2523. }
  2524. void AesEncryptBlock(const AesCtx *const Ctx, BYTE *block)
  2525. {
  2526. uint_fast8_t i;
  2527. for ( i = 0 ;; i += 4 )
  2528. {
  2529. AddRoundKey(block, &Ctx->Key[ i ]);
  2530. SubBytes(block);
  2531. ShiftRows(block);
  2532. if ( i >= ( Ctx->rounds - 1 ) << 2 ) break;
  2533. MixColumns(block);
  2534. }
  2535. AddRoundKey(block, &Ctx->Key[ Ctx->rounds << 2 ]);
  2536. }
  2537. void AesCmacV4(BYTE *Message, size_t MessageSize, BYTE *MacOut)
  2538. {
  2539. size_t i;
  2540. BYTE mac[AES_BLOCK_BYTES];
  2541. AesCtx Ctx;
  2542. AesInitKey(&Ctx, AesKeyV4, FALSE, V4_KEY_BYTES);
  2543. memset(mac, 0, sizeof(mac));
  2544. memset(Message + MessageSize, 0, AES_BLOCK_BYTES);
  2545. Message[MessageSize] = 0x80;
  2546. for (i = 0; i <= MessageSize; i += AES_BLOCK_BYTES)
  2547. {
  2548. XorBlock(Message + i, mac);
  2549. AesEncryptBlock(&Ctx, mac);
  2550. }
  2551. memcpy(MacOut, mac, AES_BLOCK_BYTES);
  2552. }
  2553. #endif
  2554. #if !defined(_CRYPTO_OPENSSL) || !defined(_USE_AES_FROM_OPENSSL)
  2555. static const BYTE SBoxR[] = {
  2556. 0x52, 0x09, 0x6A, 0xD5, 0x30, 0x36, 0xA5, 0x38, 0xBF, 0x40, 0xA3, 0x9E,
  2557. 0x81, 0xF3, 0xD7, 0xFB, 0x7C, 0xE3, 0x39, 0x82, 0x9B, 0x2F, 0xFF, 0x87,
  2558. 0x34, 0x8E, 0x43, 0x44, 0xC4, 0xDE, 0xE9, 0xCB, 0x54, 0x7B, 0x94, 0x32,
  2559. 0xA6, 0xC2, 0x23, 0x3D, 0xEE, 0x4C, 0x95, 0x0B, 0x42, 0xFA, 0xC3, 0x4E,
  2560. 0x08, 0x2E, 0xA1, 0x66, 0x28, 0xD9, 0x24, 0xB2, 0x76, 0x5B, 0xA2, 0x49,
  2561. 0x6D, 0x8B, 0xD1, 0x25, 0x72, 0xF8, 0xF6, 0x64, 0x86, 0x68, 0x98, 0x16,
  2562. 0xD4, 0xA4, 0x5C, 0xCC, 0x5D, 0x65, 0xB6, 0x92, 0x6C, 0x70, 0x48, 0x50,
  2563. 0xFD, 0xED, 0xB9, 0xDA, 0x5E, 0x15, 0x46, 0x57, 0xA7, 0x8D, 0x9D, 0x84,
  2564. 0x90, 0xD8, 0xAB, 0x00, 0x8C, 0xBC, 0xD3, 0x0A, 0xF7, 0xE4, 0x58, 0x05,
  2565. 0xB8, 0xB3, 0x45, 0x06, 0xD0, 0x2C, 0x1E, 0x8F, 0xCA, 0x3F, 0x0F, 0x02,
  2566. 0xC1, 0xAF, 0xBD, 0x03, 0x01, 0x13, 0x8A, 0x6B, 0x3A, 0x91, 0x11, 0x41,
  2567. 0x4F, 0x67, 0xDC, 0xEA, 0x97, 0xF2, 0xCF, 0xCE, 0xF0, 0xB4, 0xE6, 0x73,
  2568. 0x96, 0xAC, 0x74, 0x22, 0xE7, 0xAD, 0x35, 0x85, 0xE2, 0xF9, 0x37, 0xE8,
  2569. 0x1C, 0x75, 0xDF, 0x6E, 0x47, 0xF1, 0x1A, 0x71, 0x1D, 0x29, 0xC5, 0x89,
  2570. 0x6F, 0xB7, 0x62, 0x0E, 0xAA, 0x18, 0xBE, 0x1B, 0xFC, 0x56, 0x3E, 0x4B,
  2571. 0xC6, 0xD2, 0x79, 0x20, 0x9A, 0xDB, 0xC0, 0xFE, 0x78, 0xCD, 0x5A, 0xF4,
  2572. 0x1F, 0xDD, 0xA8, 0x33, 0x88, 0x07, 0xC7, 0x31, 0xB1, 0x12, 0x10, 0x59,
  2573. 0x27, 0x80, 0xEC, 0x5F, 0x60, 0x51, 0x7F, 0xA9, 0x19, 0xB5, 0x4A, 0x0D,
  2574. 0x2D, 0xE5, 0x7A, 0x9F, 0x93, 0xC9, 0x9C, 0xEF, 0xA0, 0xE0, 0x3B, 0x4D,
  2575. 0xAE, 0x2A, 0xF5, 0xB0, 0xC8, 0xEB, 0xBB, 0x3C, 0x83, 0x53, 0x99, 0x61,
  2576. 0x17, 0x2B, 0x04, 0x7E, 0xBA, 0x77, 0xD6, 0x26, 0xE1, 0x69, 0x14, 0x63,
  2577. 0x55, 0x21, 0x0C, 0x7D
  2578. };
  2579. static void ShiftRowsR(BYTE *state)
  2580. {
  2581. BYTE b[AES_BLOCK_BYTES];
  2582. uint_fast8_t i;
  2583. memcpy(b, state, AES_BLOCK_BYTES);
  2584. for (i = 0; i < AES_BLOCK_BYTES; i++)
  2585. state[i] = b[(i - ((i & 0x3) << 2)) & 0xf];
  2586. }
  2587. static void SubBytesR(BYTE *block)
  2588. {
  2589. uint_fast8_t i;
  2590. for (i = 0; i < AES_BLOCK_BYTES; i++)
  2591. block[i] = SBoxR[ block[i] ];
  2592. }
  2593. void AesEncryptCbc(const AesCtx *const Ctx, BYTE *restrict iv, BYTE *restrict data, size_t *restrict len)
  2594. {
  2595. // Pad up to blocksize inclusive
  2596. size_t i;
  2597. uint_fast8_t pad = (~*len & (AES_BLOCK_BYTES - 1)) + 1;
  2598. #if defined(__GNUC__) && (__GNUC__ == 4 && __GNUC_MINOR__ == 8) // gcc 4.8 memset bug https://gcc.gnu.org/bugzilla/show_bug.cgi?id=56977
  2599. for (i = 0; i < pad; i++) data[*len + i] = pad;
  2600. #else
  2601. memset(data + *len, pad, pad);
  2602. #endif
  2603. *len += pad;
  2604. if ( iv ) XorBlock(iv, data);
  2605. AesEncryptBlock(Ctx, data);
  2606. for (i = *len - AES_BLOCK_BYTES; i; i -= AES_BLOCK_BYTES)
  2607. {
  2608. XorBlock(data, data + AES_BLOCK_BYTES);
  2609. data += AES_BLOCK_BYTES;
  2610. AesEncryptBlock(Ctx, data);
  2611. }
  2612. }
  2613. void AesDecryptBlock(const AesCtx *const Ctx, BYTE *block)
  2614. {
  2615. uint_fast8_t i;
  2616. AddRoundKey(block, &Ctx->Key[ Ctx->rounds << 2 ]);
  2617. for ( i = ( Ctx->rounds - 1 ) << 2 ;; i -= 4 )
  2618. {
  2619. ShiftRowsR(block);
  2620. SubBytesR(block);
  2621. AddRoundKey(block, &Ctx->Key[ i ]);
  2622. if ( i == 0 ) break;
  2623. MixColumnsR(block);
  2624. }
  2625. }
  2626. void AesDecryptCbc(const AesCtx *const Ctx, BYTE *iv, BYTE *data, size_t len)
  2627. {
  2628. BYTE *cc;
  2629. for (cc = data + len - AES_BLOCK_BYTES; cc > data; cc -= AES_BLOCK_BYTES)
  2630. {
  2631. AesDecryptBlock(Ctx, cc);
  2632. XorBlock(cc - AES_BLOCK_BYTES, cc);
  2633. }
  2634. AesDecryptBlock(Ctx, cc);
  2635. if ( iv ) XorBlock(iv, cc);
  2636. }
  2637. #endif // _CRYPTO_OPENSSL || OPENSSL_VERSION_NUMBER < 0x10000000L
  2638. #ifndef CONFIG
  2639. #define CONFIG "config.h"
  2640. #endif // CONFIG
  2641. #include CONFIG
  2642. #include <stdio.h>
  2643. #include <string.h>
  2644. #include <stdint.h>
  2645. #include <ctype.h>
  2646. #include <time.h>
  2647. #if !defined(_WIN32)
  2648. #include <sys/socket.h>
  2649. #endif
  2650. #include "output.h"
  2651. #include "crypto.h"
  2652. #include "endian.h"
  2653. #include "kms.h"
  2654. #include "shared_globals.h"
  2655. #include "helpers.h"
  2656. #define FRIENDLY_NAME_WINDOWS "Windows"
  2657. #define FRIENDLY_NAME_OFFICE2010 "Office 2010"
  2658. #define FRIENDLY_NAME_OFFICE2013 "Office"
  2659. #ifndef NO_BASIC_PRODUCT_LIST
  2660. // Do not change the order of this list. Append items as necessary
  2661. const KmsIdList ProductList[] = {
  2662. /* 000 */ { { 0x212a64dc, 0x43b1, 0x4d3d, { 0xa3, 0x0c, 0x2f, 0xc6, 0x9d, 0x20, 0x95, 0xc6 } } /*"212a64dc-43b1-4d3d-a30c-2fc69d2095c6"*/, "Vista", EPID_WINDOWS, 4, 25 },
  2663. /* 001 */ { { 0x7fde5219, 0xfbfa, 0x484a, { 0x82, 0xc9, 0x34, 0xd1, 0xad, 0x53, 0xe8, 0x56 } } /*"7fde5219-fbfa-484a-82c9-34d1ad53e856"*/, "Windows 7", EPID_WINDOWS, 4, 25 },
  2664. /* 002 */ { { 0x3c40b358, 0x5948, 0x45af, { 0x92, 0x3b, 0x53, 0xd2, 0x1f, 0xcc, 0x7e, 0x79 } } /*"3c40b358-5948-45af-923b-53d21fcc7e79"*/, "Windows 8 VL", EPID_WINDOWS, 5, 25 },
  2665. /* 003 */ { { 0x5f94a0bb, 0xd5a0, 0x4081, { 0xa6, 0x85, 0x58, 0x19, 0x41, 0x8b, 0x2f, 0xe0 } } /*"5f94a0bb-d5a0-4081-a685-5819418b2fe0"*/, "Windows Preview", EPID_WINDOWS, 6, 25 },
  2666. /* 004 */ { { 0xbbb97b3b, 0x8ca4, 0x4a28, { 0x97, 0x17, 0x89, 0xfa, 0xbd, 0x42, 0xc4, 0xac } } /*"bbb97b3b-8ca4-4a28-9717-89fabd42c4ac"*/, "Windows 8 Retail", EPID_WINDOWS, 5, 25 },
  2667. /* 005 */ { { 0xcb8fc780, 0x2c05, 0x495a, { 0x97, 0x10, 0x85, 0xaf, 0xff, 0xc9, 0x04, 0xd7 } } /*"cb8fc780-2c05-495a-9710-85afffc904d7"*/, "Windows 8.1 VL", EPID_WINDOWS, 6, 25 },
  2668. /* 006 */ { { 0x6d646890, 0x3606, 0x461a, { 0x86, 0xab, 0x59, 0x8b, 0xb8, 0x4a, 0xce, 0x82 } } /*"6d646890-3606-461a-86ab-598bb84ace82"*/, "Windows 8.1 Retail", EPID_WINDOWS, 6, 25 },
  2669. /* 007 */ { { 0x33e156e4, 0xb76f, 0x4a52, { 0x9f, 0x91, 0xf6, 0x41, 0xdd, 0x95, 0xac, 0x48 } } /*"33e156e4-b76f-4a52-9f91-f641dd95ac48"*/, "Windows 2008 A", EPID_WINDOWS, 4, 5 },
  2670. /* 008 */ { { 0x8fe53387, 0x3087, 0x4447, { 0x89, 0x85, 0xf7, 0x51, 0x32, 0x21, 0x5a, 0xc9 } } /*"8fe53387-3087-4447-8985-f75132215ac9"*/, "Windows 2008 B", EPID_WINDOWS, 4, 5 },
  2671. /* 009 */ { { 0x8a21fdf3, 0xcbc5, 0x44eb, { 0x83, 0xf3, 0xfe, 0x28, 0x4e, 0x66, 0x80, 0xa7 } } /*"8a21fdf3-cbc5-44eb-83f3-fe284e6680a7"*/, "Windows 2008 C", EPID_WINDOWS, 4, 5 },
  2672. /* 010 */ { { 0x0fc6ccaf, 0xff0e, 0x4fae, { 0x9d, 0x08, 0x43, 0x70, 0x78, 0x5b, 0xf7, 0xed } } /*"0fc6ccaf-ff0e-4fae-9d08-4370785bf7ed"*/, "Windows 2008 R2 A", EPID_WINDOWS, 4, 5 },
  2673. /* 011 */ { { 0xca87f5b6, 0xcd46, 0x40c0, { 0xb0, 0x6d, 0x8e, 0xcd, 0x57, 0xa4, 0x37, 0x3f } } /*"ca87f5b6-cd46-40c0-b06d-8ecd57a4373f"*/, "Windows 2008 R2 B", EPID_WINDOWS, 4, 5 },
  2674. /* 012 */ { { 0xb2ca2689, 0xa9a8, 0x42d7, { 0x93, 0x8d, 0xcf, 0x8e, 0x9f, 0x20, 0x19, 0x58 } } /*"b2ca2689-a9a8-42d7-938d-cf8e9f201958"*/, "Windows 2008 R2 C", EPID_WINDOWS, 4, 5 },
  2675. /* 013 */ { { 0x8665cb71, 0x468c, 0x4aa3, { 0xa3, 0x37, 0xcb, 0x9b, 0xc9, 0xd5, 0xea, 0xac } } /*"8665cb71-468c-4aa3-a337-cb9bc9d5eaac"*/, "Windows 2012", EPID_WINDOWS, 5, 5 },
  2676. /* 014 */ { { 0x8456EFD3, 0x0C04, 0x4089, { 0x87, 0x40, 0x5b, 0x72, 0x38, 0x53, 0x5a, 0x65 } } /*"8456EFD3-0C04-4089-8740-5B7238535A65"*/, "Windows 2012 R2", EPID_WINDOWS, 6, 5 },
  2677. /* 015 */ { { 0xe85af946, 0x2e25, 0x47b7, { 0x83, 0xe1, 0xbe, 0xbc, 0xeb, 0xea, 0xc6, 0x11 } } /*"e85af946-2e25-47b7-83e1-bebcebeac611"*/, "Office 2010", EPID_OFFICE2010, 4, 5 },
  2678. /* 016 */ { { 0xe6a6f1bf, 0x9d40, 0x40c3, { 0xaa, 0x9f, 0xc7, 0x7b, 0xa2, 0x15, 0x78, 0xc0 } } /*"e6a6f1bf-9d40-40c3-aa9f-c77ba21578c0"*/, "Office 2013", EPID_OFFICE2013, 6, 5 },
  2679. /* 017 */ { { 0x6d5f5270, 0x31ac, 0x433e, { 0xb9, 0x0a, 0x39, 0x89, 0x29, 0x23, 0xc6, 0x57 } } /*"6d5f5270-31ac-433e-b90a-39892923c657"*/, "Windows Server Preview", EPID_WINDOWS, 6, 5 },
  2680. /* 018 */ { { 0x85b5f61b, 0x320b, 0x4be3, { 0x81, 0x4a, 0xb7, 0x6b, 0x2b, 0xfa, 0xfc, 0x82 } } /*"85b5f61b-320b-4be3-814a-b76b2bfafc82"*/, "Office 2016", EPID_OFFICE2013, 6, 5 },
  2681. /* 019 */ { { 0x58e2134f, 0x8e11, 0x4d17, { 0x9c, 0xb2, 0x91, 0x06, 0x9c, 0x15, 0x11, 0x48 } } /*"58e2134f-8e11-4d17-9cb2-91069c151148"*/, "Windows 10 VL", EPID_WINDOWS, 6, 25 },
  2682. /* 020 */ { { 0xe1c51358, 0xfe3e, 0x4203, { 0xa4, 0xa2, 0x3b, 0x6b, 0x20, 0xc9, 0x73, 0x4e } } /*"e1c51358-fe3e-4203-a4a2-3b6b20c9734e"*/, "Windows 10 Retail", EPID_WINDOWS, 6, 25 },
  2683. /* 021 */ { { 0x00000000, 0x0000, 0x0000, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }, NULL, NULL, 0, 0 }
  2684. };
  2685. #endif
  2686. // Application ID is used by KMS server to count KeyManagementServiceCurrentCount
  2687. // Do not change the order of this list. Append items as necessary
  2688. const KmsIdList AppList[] = {
  2689. /* 000 */ { { 0x55c92734, 0xd682, 0x4d71, { 0x98, 0x3e, 0xd6, 0xec, 0x3f, 0x16, 0x05, 0x9f } } /*"55C92734-D682-4D71-983E-D6EC3F16059F"*/, FRIENDLY_NAME_WINDOWS, EPID_WINDOWS, 0, 0},
  2690. /* 001 */ { { 0x59A52881, 0xa989, 0x479d, { 0xaf, 0x46, 0xf2, 0x75, 0xc6, 0x37, 0x06, 0x63 } } /*"59A52881-A989-479D-AF46-F275C6370663"*/, FRIENDLY_NAME_OFFICE2010, EPID_OFFICE2010, 0, 0},
  2691. /* 002 */ { { 0x0FF1CE15, 0xA989, 0x479D, { 0xaf, 0x46, 0xf2, 0x75, 0xc6, 0x37, 0x06, 0x63 } } /*"0FF1CE15-A989-479D-AF46-F275C6370663"*/, FRIENDLY_NAME_OFFICE2013, EPID_OFFICE2013, 0, 0},
  2692. /* 003 */ { { 0x00000000, 0x0000, 0x0000, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }, NULL, NULL, 0, 0 }
  2693. };
  2694. #ifndef NO_EXTENDED_PRODUCT_LIST
  2695. const KmsIdList ExtendedProductList [] = {
  2696. // Windows Server
  2697. { { 0xad2542d4, 0x9154, 0x4c6d, { 0x8a, 0x44, 0x30, 0xf1, 0x1e, 0xe9, 0x69, 0x89, } } /*ad2542d4-9154-4c6d-8a44-30f11ee96989*/, "Windows Server 2008 Standard", EPID_WINDOWS, APP_ID_WINDOWS, KMS_ID_WIN2008A },
  2698. { { 0x2401e3d0, 0xc50a, 0x4b58, { 0x87, 0xb2, 0x7e, 0x79, 0x4b, 0x7d, 0x26, 0x07, } } /*2401e3d0-c50a-4b58-87b2-7e794b7d2607*/, "Windows Server 2008 Standard V", EPID_WINDOWS, APP_ID_WINDOWS, KMS_ID_WIN2008A },
  2699. { { 0x68b6e220, 0xcf09, 0x466b, { 0x92, 0xd3, 0x45, 0xcd, 0x96, 0x4b, 0x95, 0x09, } } /*68b6e220-cf09-466b-92d3-45cd964b9509*/, "Windows Server 2008 Datacenter", EPID_WINDOWS, APP_ID_WINDOWS, KMS_ID_WIN2008C },
  2700. { { 0xfd09ef77, 0x5647, 0x4eff, { 0x80, 0x9c, 0xaf, 0x2b, 0x64, 0x65, 0x9a, 0x45, } } /*fd09ef77-5647-4eff-809c-af2b64659a45*/, "Windows Server 2008 Datacenter V", EPID_WINDOWS, APP_ID_WINDOWS, KMS_ID_WIN2008C },
  2701. { { 0xc1af4d90, 0xd1bc, 0x44ca, { 0x85, 0xd4, 0x00, 0x3b, 0xa3, 0x3d, 0xb3, 0xb9, } } /*c1af4d90-d1bc-44ca-85d4-003ba33db3b9*/, "Windows Server 2008 Enterprise", EPID_WINDOWS, APP_ID_WINDOWS, KMS_ID_WIN2008B },
  2702. { { 0x8198490a, 0xadd0, 0x47b2, { 0xb3, 0xba, 0x31, 0x6b, 0x12, 0xd6, 0x47, 0xb4, } } /*8198490a-add0-47b2-b3ba-316b12d647b4*/, "Windows Server 2008 Enterprise V", EPID_WINDOWS, APP_ID_WINDOWS, KMS_ID_WIN2008B },
  2703. { { 0xddfa9f7c, 0xf09e, 0x40b9, { 0x8c, 0x1a, 0xbe, 0x87, 0x7a, 0x9a, 0x7f, 0x4b, } } /*ddfa9f7c-f09e-40b9-8c1a-be877a9a7f4b*/, "Windows Server 2008 Web", EPID_WINDOWS, APP_ID_WINDOWS, KMS_ID_WIN2008A },
  2704. { { 0x7afb1156, 0x2c1d, 0x40fc, { 0xb2, 0x60, 0xaa, 0xb7, 0x44, 0x2b, 0x62, 0xfe, } } /*7afb1156-2c1d-40fc-b260-aab7442b62fe*/, "Windows Server 2008 Compute Cluster", EPID_WINDOWS, APP_ID_WINDOWS, KMS_ID_WIN2008C },
  2705. { { 0x68531fb9, 0x5511, 0x4989, { 0x97, 0xbe, 0xd1, 0x1a, 0x0f, 0x55, 0x63, 0x3f, } } /*68531fb9-5511-4989-97be-d11a0f55633f*/, "Windows Server 2008 R2 Standard", EPID_WINDOWS, APP_ID_WINDOWS, KMS_ID_WIN2008R2A },
  2706. { { 0x7482e61b, 0xc589, 0x4b7f, { 0x8e, 0xcc, 0x46, 0xd4, 0x55, 0xac, 0x3b, 0x87, } } /*7482e61b-c589-4b7f-8ecc-46d455ac3b87*/, "Windows Server 2008 R2 Datacenter", EPID_WINDOWS, APP_ID_WINDOWS, KMS_ID_WIN2008R2C },
  2707. { { 0x620e2b3d, 0x09e7, 0x42fd, { 0x80, 0x2a, 0x17, 0xa1, 0x36, 0x52, 0xfe, 0x7a, } } /*620e2b3d-09e7-42fd-802a-17a13652fe7a*/, "Windows Server 2008 R2 Enterprise", EPID_WINDOWS, APP_ID_WINDOWS, KMS_ID_WIN2008R2B },
  2708. { { 0xa78b8bd9, 0x8017, 0x4df5, { 0xb8, 0x6a, 0x09, 0xf7, 0x56, 0xaf, 0xfa, 0x7c, } } /*a78b8bd9-8017-4df5-b86a-09f756affa7c*/, "Windows Server 2008 R2 Web", EPID_WINDOWS, APP_ID_WINDOWS, KMS_ID_WIN2008R2A },
  2709. { { 0xcda18cf3, 0xc196, 0x46ad, { 0xb2, 0x89, 0x60, 0xc0, 0x72, 0x86, 0x99, 0x94, } } /*cda18cf3-c196-46ad-b289-60c072869994*/, "Windows Server 2008 R2 Compute Cluster", EPID_WINDOWS, APP_ID_WINDOWS, KMS_ID_WIN2008R2C },
  2710. { { 0xd3643d60, 0x0c42, 0x412d, { 0xa7, 0xd6, 0x52, 0xe6, 0x63, 0x53, 0x27, 0xf6, } } /*d3643d60-0c42-412d-a7d6-52e6635327f6*/, "Windows Server 2012 Datacenter", EPID_WINDOWS, APP_ID_WINDOWS, KMS_ID_WIN2012 },
  2711. { { 0xf0f5ec41, 0x0d55, 0x4732, { 0xaf, 0x02, 0x44, 0x0a, 0x44, 0xa3, 0xcf, 0x0f, } } /*f0f5ec41-0d55-4732-af02-440a44a3cf0f*/, "Windows Server 2012 Standard", EPID_WINDOWS, APP_ID_WINDOWS, KMS_ID_WIN2012 },
  2712. { { 0x95fd1c83, 0x7df5, 0x494a, { 0xbe, 0x8b, 0x13, 0x00, 0xe1, 0xc9, 0xd1, 0xcd, } } /*95fd1c83-7df5-494a-be8b-1300e1c9d1cd*/, "Windows Server 2012 MultiPoint Premium", EPID_WINDOWS, APP_ID_WINDOWS, KMS_ID_WIN2012 },
  2713. { { 0x7d5486c7, 0xe120, 0x4771, { 0xb7, 0xf1, 0x7b, 0x56, 0xc6, 0xd3, 0x17, 0x0c, } } /*7d5486c7-e120-4771-b7f1-7b56c6d3170c*/, "Windows Server 2012 MultiPoint Standard", EPID_WINDOWS, APP_ID_WINDOWS, KMS_ID_WIN2012 },
  2714. { { 0x00091344, 0x1ea4, 0x4f37, { 0xb7, 0x89, 0x01, 0x75, 0x0b, 0xa6, 0x98, 0x8c, } } /*00091344-1ea4-4f37-b789-01750ba6988c*/, "Windows Server 2012 R2 Datacenter", EPID_WINDOWS, APP_ID_WINDOWS, KMS_ID_WIN2012R2 },
  2715. { { 0xb3ca044e, 0xa358, 0x4d68, { 0x98, 0x83, 0xaa, 0xa2, 0x94, 0x1a, 0xca, 0x99, } } /*b3ca044e-a358-4d68-9883-aaa2941aca99*/, "Windows Server 2012 R2 Standard", EPID_WINDOWS, APP_ID_WINDOWS, KMS_ID_WIN2012R2 },
  2716. { { 0xb743a2be, 0x68d4, 0x4dd3, { 0xaf, 0x32, 0x92, 0x42, 0x5b, 0x7b, 0xb6, 0x23, } } /*b743a2be-68d4-4dd3-af32-92425b7bb623*/, "Windows Server 2012 R2 Cloud Storage", EPID_WINDOWS, APP_ID_WINDOWS, KMS_ID_WIN2012R2 },
  2717. { { 0x21db6ba4, 0x9a7b, 0x4a14, { 0x9e, 0x29, 0x64, 0xa6, 0x0c, 0x59, 0x30, 0x1d, } } /*21db6ba4-9a7b-4a14-9e29-64a60c59301d*/, "Windows Server 2012 R2 Essentials", EPID_WINDOWS, APP_ID_WINDOWS, KMS_ID_WIN2012R2 },
  2718. { { 0xba947c44, 0xd19d, 0x4786, { 0xb6, 0xae, 0x22, 0x77, 0x0b, 0xc9, 0x4c, 0x54, } } /*ba947c44-d19d-4786-b6ae-22770bc94c54*/, "Windows Server 2016 Datacenter Preview", EPID_WINDOWS, APP_ID_WINDOWS, KMS_ID_WIN_SRV_BETA },
  2719. // Windows 10 Preview
  2720. # ifdef INCLUDE_BETAS
  2721. { { 0x6496e59d, 0x89dc, 0x49eb, { 0xa3, 0x53, 0x09, 0xce, 0xb9, 0x40, 0x48, 0x45, } } /*6496e59d-89dc-49eb-a353-09ceb9404845*/, "Windows 10 Core Preview", EPID_WINDOWS, APP_ID_WINDOWS, KMS_ID_WIN_BETA },
  2722. { { 0xa4383e6b, 0xdada, 0x423d, { 0xa4, 0x3d, 0xf2, 0x56, 0x78, 0x42, 0x96, 0x76, } } /*a4383e6b-dada-423d-a43d-f25678429676*/, "Windows 10 Professional Preview", EPID_WINDOWS, APP_ID_WINDOWS, KMS_ID_WIN_BETA },
  2723. { { 0xcf59a07b, 0x1a2a, 0x4be0, { 0xbf, 0xe0, 0x42, 0x3b, 0x58, 0x23, 0xe6, 0x63, } } /*cf59a07b-1a2a-4be0-bfe0-423b5823e663*/, "Windows 10 Professional WMC Preview", EPID_WINDOWS, APP_ID_WINDOWS, KMS_ID_WIN_BETA },
  2724. { { 0xcde952c7, 0x2f96, 0x4d9d, { 0x8f, 0x2b, 0x2d, 0x34, 0x9f, 0x64, 0xfc, 0x51, } } /*cde952c7-2f96-4d9d-8f2b-2d349f64fc51*/, "Windows 10 Enterprise Preview", EPID_WINDOWS, APP_ID_WINDOWS, KMS_ID_WIN_BETA },
  2725. # endif
  2726. // Windows 10
  2727. { { 0x73111121, 0x5638, 0x40f6, { 0xbc, 0x11, 0xf1, 0xd7, 0xb0, 0xd6, 0x43, 0x00, } } /*73111121-5638-40f6-bc11-f1d7b0d64300*/, "Windows 10 Enterprise", EPID_WINDOWS, APP_ID_WINDOWS, KMS_ID_WIN10_VL },
  2728. { { 0xe272e3e2, 0x732f, 0x4c65, { 0xa8, 0xf0, 0x48, 0x47, 0x47, 0xd0, 0xd9, 0x47, } } /*e272e3e2-732f-4c65-a8f0-484747d0d947*/, "Windows 10 Enterprise N", EPID_WINDOWS, APP_ID_WINDOWS, KMS_ID_WIN10_VL},
  2729. { { 0x7b51a46c, 0x0c04, 0x4e8f, { 0x9a, 0xf4, 0x84, 0x96, 0xcc, 0xa9, 0x0d, 0x5e, } } /*7b51a46c-0c04-4e8f-9af4-8496cca90d5e*/, "Windows 10 Enterprise LTSB", EPID_WINDOWS, APP_ID_WINDOWS, KMS_ID_WIN10_VL},
  2730. { { 0x87b838b7, 0x41b6, 0x4590, { 0x83, 0x18, 0x57, 0x97, 0x95, 0x1d, 0x85, 0x29, } } /*87b838b7-41b6-4590-8318-5797951d8529*/, "Windows 10 Enterprise LTSB N", EPID_WINDOWS, APP_ID_WINDOWS, KMS_ID_WIN10_VL},
  2731. { { 0xe0c42288, 0x980c, 0x4788, { 0xa0, 0x14, 0xc0, 0x80, 0xd2, 0xe1, 0x92, 0x6e, } } /*e0c42288-980c-4788-a014-c080d2e1926e*/, "Windows 10 Education", EPID_WINDOWS, APP_ID_WINDOWS, KMS_ID_WIN10_VL},
  2732. { { 0x3c102355, 0xd027, 0x42c6, { 0xad, 0x23, 0x2e, 0x7e, 0xf8, 0xa0, 0x25, 0x85, } } /*3c102355-d027-42c6-ad23-2e7ef8a02585*/, "Windows 10 Education N", EPID_WINDOWS, APP_ID_WINDOWS, KMS_ID_WIN10_VL},
  2733. { { 0x2de67392, 0xb7a7, 0x462a, { 0xb1, 0xca, 0x10, 0x8d, 0xd1, 0x89, 0xf5, 0x88, } } /*2de67392-b7a7-462a-b1ca-108dd189f588*/, "Windows 10 Professional", EPID_WINDOWS, APP_ID_WINDOWS, KMS_ID_WIN10_VL },
  2734. { { 0xa80b5abf, 0x75ad, 0x428b, { 0xb0, 0x5d, 0xa4, 0x7d, 0x2d, 0xff, 0xee, 0xbf, } } /*a80b5abf-76ad-428b-b05d-a47d2dffeebf*/, "Windows 10 Professional N", EPID_WINDOWS, APP_ID_WINDOWS, KMS_ID_WIN10_VL},
  2735. { { 0x58e97c99, 0xf377, 0x4ef1, { 0x81, 0xd5, 0x4a, 0xd5, 0x52, 0x2b, 0x5f, 0xd8, } } /*58e97c99-f377-4ef1-81d5-4ad5522b5fd8*/, "Windows 10 Home", EPID_WINDOWS, APP_ID_WINDOWS, KMS_ID_WIN10_RETAIL},
  2736. { { 0x7b9e1751, 0xa8da, 0x4f75, { 0x95, 0x60, 0x5f, 0xad, 0xfe, 0x3d, 0x8e, 0x38, } } /*7b9e1751-a8da-4f75-9560-5fadfe3d8e38*/, "Windows 10 Home N", EPID_WINDOWS, APP_ID_WINDOWS, KMS_ID_WIN10_RETAIL},
  2737. { { 0xcd918a57, 0xa41b, 0x4c82, { 0x8d, 0xce, 0x1a, 0x53, 0x8e, 0x22, 0x1a, 0x83, } } /*cd918a57-a41b-4c82-8dce-1a538e221a83*/, "Windows 10 Home Single Language", EPID_WINDOWS, APP_ID_WINDOWS, KMS_ID_WIN10_RETAIL},
  2738. { { 0xa9107544, 0xf4a0, 0x4053, { 0xa9, 0x6a, 0x14, 0x79, 0xab, 0xde, 0xf9, 0x12, } } /*a9107544-f4a0-4053-a96a-1479abdef912*/, "Windows 10 Home Country Specific", EPID_WINDOWS, APP_ID_WINDOWS, KMS_ID_WIN10_RETAIL},
  2739. // Windows 8.x
  2740. # ifdef INCLUDE_BETAS
  2741. { { 0x2B9C337F, 0x7A1D, 0x4271, { 0x90, 0xA3, 0xC6, 0x85, 0x5A, 0x2B, 0x8A, 0x1C, } } /*2B9C337F-7A1D-4271-90A3-C6855A2B8A1C*/, "Windows 8.x Preview", EPID_WINDOWS, APP_ID_WINDOWS, KMS_ID_WIN_BETA },
  2742. { { 0x631EAD72, 0xA8AB, 0x4DF8, { 0xBB, 0xDF, 0x37, 0x20, 0x29, 0x98, 0x9B, 0xDD, } } /*631EAD72-A8AB-4DF8-BBDF-372029989BDD*/, "Windows 8.x Preview ARM", EPID_WINDOWS, APP_ID_WINDOWS, KMS_ID_WIN_BETA },
  2743. # endif
  2744. { { 0x81671aaf, 0x79d1, 0x4eb1, { 0xb0, 0x04, 0x8c, 0xbb, 0xe1, 0x73, 0xaf, 0xea, } } /*81671aaf-79d1-4eb1-b004-8cbbe173afea*/, "Windows 8.1 Enterprise", EPID_WINDOWS, APP_ID_WINDOWS, KMS_ID_WIN81_VL },
  2745. { { 0x113e705c, 0xfa49, 0x48a4, { 0xbe, 0xea, 0x7d, 0xd8, 0x79, 0xb4, 0x6b, 0x14, } } /*113e705c-fa49-48a4-beea-7dd879b46b14*/, "Windows 8.1 Enterprise N", EPID_WINDOWS, APP_ID_WINDOWS, KMS_ID_WIN81_VL },
  2746. { { 0x096ce63d, 0x4fac, 0x48a9, { 0x82, 0xa9, 0x61, 0xae, 0x9e, 0x80, 0x0e, 0x5f, } } /*096ce63d-4fac-48a9-82a9-61ae9e800e5f*/, "Windows 8.1 Professional WMC", EPID_WINDOWS, APP_ID_WINDOWS, KMS_ID_WIN81_RETAIL },
  2747. { { 0xc06b6981, 0xd7fd, 0x4a35, { 0xb7, 0xb4, 0x05, 0x47, 0x42, 0xb7, 0xaf, 0x67, } } /*c06b6981-d7fd-4a35-b7b4-054742b7af67*/, "Windows 8.1 Professional", EPID_WINDOWS, APP_ID_WINDOWS, KMS_ID_WIN81_VL },
  2748. { { 0x7476d79f, 0x8e48, 0x49b4, { 0xab, 0x63, 0x4d, 0x0b, 0x81, 0x3a, 0x16, 0xe4, } } /*7476d79f-8e48-49b4-ab63-4d0b813a16e4*/, "Windows 8.1 Professional N", EPID_WINDOWS, APP_ID_WINDOWS, KMS_ID_WIN81_VL },
  2749. { { 0xfe1c3238, 0x432a, 0x43a1, { 0x8e, 0x25, 0x97, 0xe7, 0xd1, 0xef, 0x10, 0xf3, } } /*fe1c3238-432a-43a1-8e25-97e7d1ef10f3*/, "Windows 8.1 Core", EPID_WINDOWS, APP_ID_WINDOWS, KMS_ID_WIN81_RETAIL },
  2750. { { 0x78558a64, 0xdc19, 0x43fe, { 0xa0, 0xd0, 0x80, 0x75, 0xb2, 0xa3, 0x70, 0xa3, } } /*78558a64-dc19-43fe-a0d0-8075b2a370a3*/, "Windows 8.1 Core N", EPID_WINDOWS, APP_ID_WINDOWS, KMS_ID_WIN81_RETAIL },
  2751. { { 0xffee456a, 0xcd87, 0x4390, { 0x8e, 0x07, 0x16, 0x14, 0x6c, 0x67, 0x2f, 0xd0, } } /*ffee456a-cd87-4390-8e07-16146c672fd0*/, "Windows 8.1 Core ARM", EPID_WINDOWS, APP_ID_WINDOWS, KMS_ID_WIN81_RETAIL },
  2752. { { 0xc72c6a1d, 0xf252, 0x4e7e, { 0xbd, 0xd1, 0x3f, 0xca, 0x34, 0x2a, 0xcb, 0x35, } } /*c72c6a1d-f252-4e7e-bdd1-3fca342acb35*/, "Windows 8.1 Core Single Language", EPID_WINDOWS, APP_ID_WINDOWS, KMS_ID_WIN81_RETAIL },
  2753. { { 0xdb78b74f, 0xef1c, 0x4892, { 0xab, 0xfe, 0x1e, 0x66, 0xb8, 0x23, 0x1d, 0xf6, } } /*db78b74f-ef1c-4892-abfe-1e66b8231df6*/, "Windows 8.1 Core Country Specific", EPID_WINDOWS, APP_ID_WINDOWS, KMS_ID_WIN81_RETAIL },
  2754. { { 0xe9942b32, 0x2e55, 0x4197, { 0xb0, 0xbd, 0x5f, 0xf5, 0x8c, 0xba, 0x88, 0x60, } } /*e9942b32-2e55-4197-b0bd-5ff58cba8860*/, "Windows 8.1 Core Connected", EPID_WINDOWS, APP_ID_WINDOWS, KMS_ID_WIN81_VL },
  2755. { { 0xc6ddecd6, 0x2354, 0x4c19, { 0x90, 0x9b, 0x30, 0x6a, 0x30, 0x58, 0x48, 0x4e, } } /*c6ddecd6-2354-4c19-909b-306a3058484e*/, "Windows 8.1 Core Connected N", EPID_WINDOWS, APP_ID_WINDOWS, KMS_ID_WIN81_VL },
  2756. { { 0xb8f5e3a3, 0xed33, 0x4608, { 0x81, 0xe1, 0x37, 0xd6, 0xc9, 0xdc, 0xfd, 0x9c, } } /*b8f5e3a3-ed33-4608-81e1-37d6c9dcfd9c*/, "Windows 8.1 Core Connected Single Language", EPID_WINDOWS, APP_ID_WINDOWS, KMS_ID_WIN81_VL },
  2757. { { 0xba998212, 0x460a, 0x44db, { 0xbf, 0xb5, 0x71, 0xbf, 0x09, 0xd1, 0xc6, 0x8b, } } /*ba998212-460a-44db-bfb5-71bf09d1c68b*/, "Windows 8.1 Core Connected Country Specific", EPID_WINDOWS, APP_ID_WINDOWS, KMS_ID_WIN81_VL },
  2758. { { 0xe58d87b5, 0x8126, 0x4580, { 0x80, 0xfb, 0x86, 0x1b, 0x22, 0xf7, 0x92, 0x96, } } /*e58d87b5-8126-4580-80fb-861b22f79296*/, "Windows 8.1 Professional Student", EPID_WINDOWS, APP_ID_WINDOWS, KMS_ID_WIN81_RETAIL },
  2759. { { 0xcab491c7, 0xa918, 0x4f60, { 0xb5, 0x02, 0xda, 0xb7, 0x5e, 0x33, 0x4f, 0x40, } } /*cab491c7-a918-4f60-b502-dab75e334f40*/, "Windows 8.1 Professional Student N", EPID_WINDOWS, APP_ID_WINDOWS, KMS_ID_WIN81_RETAIL },
  2760. { { 0xa00018a3, 0xf20f, 0x4632, { 0xbf, 0x7c, 0x8d, 0xaa, 0x53, 0x51, 0xc9, 0x14, } } /*a00018a3-f20f-4632-bf7c-8daa5351c914*/, "Windows 8 Professional WMC", EPID_WINDOWS, APP_ID_WINDOWS, KMS_ID_WIN8_RETAIL },
  2761. { { 0xa98bcd6d, 0x5343, 0x4603, { 0x8a, 0xfe, 0x59, 0x08, 0xe4, 0x61, 0x11, 0x12, } } /*a98bcd6d-5343-4603-8afe-5908e4611112*/, "Windows 8 Professional", EPID_WINDOWS, APP_ID_WINDOWS, KMS_ID_WIN8_VL },
  2762. { { 0xebf245c1, 0x29a8, 0x4daf, { 0x9c, 0xb1, 0x38, 0xdf, 0xc6, 0x08, 0xa8, 0xc8, } } /*ebf245c1-29a8-4daf-9cb1-38dfc608a8c8*/, "Windows 8 Professional N", EPID_WINDOWS, APP_ID_WINDOWS, KMS_ID_WIN8_VL },
  2763. { { 0x458e1bec, 0x837a, 0x45f6, { 0xb9, 0xd5, 0x92, 0x5e, 0xd5, 0xd2, 0x99, 0xde, } } /*458e1bec-837a-45f6-b9d5-925ed5d299de*/, "Windows 8 Enterprise", EPID_WINDOWS, APP_ID_WINDOWS, KMS_ID_WIN8_VL },
  2764. { { 0xe14997e7, 0x800a, 0x4cf7, { 0xad, 0x10, 0xde, 0x4b, 0x45, 0xb5, 0x78, 0xdb, } } /*e14997e7-800a-4cf7-ad10-de4b45b578db*/, "Windows 8 Enterprise N", EPID_WINDOWS, APP_ID_WINDOWS, KMS_ID_WIN8_VL },
  2765. { { 0xc04ed6bf, 0x55c8, 0x4b47, { 0x9f, 0x8e, 0x5a, 0x1f, 0x31, 0xce, 0xee, 0x60, } } /*c04ed6bf-55c8-4b47-9f8e-5a1f31ceee60*/, "Windows 8 Core", EPID_WINDOWS, APP_ID_WINDOWS, KMS_ID_WIN8_RETAIL },
  2766. { { 0x197390a0, 0x65f6, 0x4a95, { 0xbd, 0xc4, 0x55, 0xd5, 0x8a, 0x3b, 0x02, 0x53, } } /*197390a0-65f6-4a95-bdc4-55d58a3b0253*/, "Windows 8 Core N", EPID_WINDOWS, APP_ID_WINDOWS, KMS_ID_WIN8_RETAIL },
  2767. { { 0x9d5584a2, 0x2d85, 0x419a, { 0x98, 0x2c, 0xa0, 0x08, 0x88, 0xbb, 0x9d, 0xdf, } } /*9d5584a2-2d85-419a-982c-a00888bb9ddf*/, "Windows 8 Core Country Specific", EPID_WINDOWS, APP_ID_WINDOWS, KMS_ID_WIN8_RETAIL },
  2768. { { 0x8860fcd4, 0xa77b, 0x4a20, { 0x90, 0x45, 0xa1, 0x50, 0xff, 0x11, 0xd6, 0x09, } } /*8860fcd4-a77b-4a20-9045-a150ff11d609*/, "Windows 8 Core Single Language", EPID_WINDOWS, APP_ID_WINDOWS, KMS_ID_WIN8_RETAIL },
  2769. // Windows 7
  2770. { { 0xae2ee509, 0x1b34, 0x41c0, { 0xac, 0xb7, 0x6d, 0x46, 0x50, 0x16, 0x89, 0x15, } } /*ae2ee509-1b34-41c0-acb7-6d4650168915*/, "Windows 7 Enterprise", EPID_WINDOWS, APP_ID_WINDOWS, KMS_ID_WIN7 },
  2771. { { 0x1cb6d605, 0x11b3, 0x4e14, { 0xbb, 0x30, 0xda, 0x91, 0xc8, 0xe3, 0x98, 0x3a, } } /*1cb6d605-11b3-4e14-bb30-da91c8e3983a*/, "Windows 7 Enterprise N", EPID_WINDOWS, APP_ID_WINDOWS, KMS_ID_WIN7 },
  2772. { { 0xb92e9980, 0xb9d5, 0x4821, { 0x9c, 0x94, 0x14, 0x0f, 0x63, 0x2f, 0x63, 0x12, } } /*b92e9980-b9d5-4821-9c94-140f632f6312*/, "Windows 7 Professional", EPID_WINDOWS, APP_ID_WINDOWS, KMS_ID_WIN7 },
  2773. { { 0x54a09a0d, 0xd57b, 0x4c10, { 0x8b, 0x69, 0xa8, 0x42, 0xd6, 0x59, 0x0a, 0xd5, } } /*54a09a0d-d57b-4c10-8b69-a842d6590ad5*/, "Windows 7 Professional N", EPID_WINDOWS, APP_ID_WINDOWS, KMS_ID_WIN7 },
  2774. // Windows Vista
  2775. { { 0xcfd8ff08, 0xc0d7, 0x452b, { 0x9f, 0x60, 0xef, 0x5c, 0x70, 0xc3, 0x20, 0x94, } } /*cfd8ff08-c0d7-452b-9f60-ef5c70c32094*/, "Windows Vista Enterprise", EPID_WINDOWS, APP_ID_WINDOWS, KMS_ID_VISTA },
  2776. { { 0xd4f54950, 0x26f2, 0x4fb4, { 0xba, 0x21, 0xff, 0xab, 0x16, 0xaf, 0xca, 0xde, } } /*d4f54950-26f2-4fb4-ba21-ffab16afcade*/, "Windows Vista Enterprise N", EPID_WINDOWS, APP_ID_WINDOWS, KMS_ID_VISTA },
  2777. { { 0x4f3d1606, 0x3fea, 0x4c01, { 0xbe, 0x3c, 0x8d, 0x67, 0x1c, 0x40, 0x1e, 0x3b, } } /*4f3d1606-3fea-4c01-be3c-8d671c401e3b*/, "Windows Vista Business", EPID_WINDOWS, APP_ID_WINDOWS, KMS_ID_VISTA },
  2778. { { 0x2c682dc2, 0x8b68, 0x4f63, { 0xa1, 0x65, 0xae, 0x29, 0x1d, 0x4c, 0xf1, 0x38, } } /*2c682dc2-8b68-4f63-a165-ae291d4cf138*/, "Windows Vista Business N", EPID_WINDOWS, APP_ID_WINDOWS, KMS_ID_VISTA },
  2779. // Windows Embedded
  2780. { { 0xaa6dd3aa, 0xc2b4, 0x40e2, { 0xa5, 0x44, 0xa6, 0xbb, 0xb3, 0xf5, 0xc3, 0x95, } } /*aa6dd3aa-c2b4-40e2-a544-a6bbb3f5c395*/, "Windows ThinPC", EPID_WINDOWS, APP_ID_WINDOWS, KMS_ID_WIN7 },
  2781. { { 0xdb537896, 0x376f, 0x48ae, { 0xa4, 0x92, 0x53, 0xd0, 0x54, 0x77, 0x73, 0xd0, } } /*db537896-376f-48ae-a492-53d0547773d0*/, "Windows Embedded POSReady 7", EPID_WINDOWS, APP_ID_WINDOWS, KMS_ID_WIN7 },
  2782. { { 0x0ab82d54, 0x47f4, 0x4acb, { 0x81, 0x8c, 0xcc, 0x5b, 0xf0, 0xec, 0xb6, 0x49, } } /*0ab82d54-47f4-4acb-818c-cc5bf0ecb649*/, "Windows Embedded Industry 8.1", EPID_WINDOWS, APP_ID_WINDOWS, KMS_ID_WIN81_VL },
  2783. { { 0xcd4e2d9f, 0x5059, 0x4a50, { 0xa9, 0x2d, 0x05, 0xd5, 0xbb, 0x12, 0x67, 0xc7, } } /*cd4e2d9f-5059-4a50-a92d-05d5bb1267c7*/, "Windows Embedded Industry E 8.1", EPID_WINDOWS, APP_ID_WINDOWS, KMS_ID_WIN81_VL },
  2784. { { 0xf7e88590, 0xdfc7, 0x4c78, { 0xbc, 0xcb, 0x6f, 0x38, 0x65, 0xb9, 0x9d, 0x1a, } } /*f7e88590-dfc7-4c78-bccb-6f3865b99d1a*/, "Windows Embedded Industry A 8.1", EPID_WINDOWS, APP_ID_WINDOWS, KMS_ID_WIN81_VL },
  2785. // Office 2010
  2786. { { 0x8ce7e872, 0x188c, 0x4b98, { 0x9d, 0x90, 0xf8, 0xf9, 0x0b, 0x7a, 0xad, 0x02, } } /*8ce7e872-188c-4b98-9d90-f8f90b7aad02*/, "Office Access 2010", EPID_OFFICE2010, APP_ID_OFFICE2010, KMS_ID_OFFICE2010 },
  2787. { { 0xcee5d470, 0x6e3b, 0x4fcc, { 0x8c, 0x2b, 0xd1, 0x74, 0x28, 0x56, 0x8a, 0x9f, } } /*cee5d470-6e3b-4fcc-8c2b-d17428568a9f*/, "Office Excel 2010", EPID_OFFICE2010, APP_ID_OFFICE2010, KMS_ID_OFFICE2010 },
  2788. { { 0x8947d0b8, 0xc33b, 0x43e1, { 0x8c, 0x56, 0x9b, 0x67, 0x4c, 0x05, 0x28, 0x32, } } /*8947d0b8-c33b-43e1-8c56-9b674c052832*/, "Office Groove 2010", EPID_OFFICE2010, APP_ID_OFFICE2010, KMS_ID_OFFICE2010 },
  2789. { { 0xca6b6639, 0x4ad6, 0x40ae, { 0xa5, 0x75, 0x14, 0xde, 0xe0, 0x7f, 0x64, 0x30, } } /*ca6b6639-4ad6-40ae-a575-14dee07f6430*/, "Office InfoPath 2010", EPID_OFFICE2010, APP_ID_OFFICE2010, KMS_ID_OFFICE2010 },
  2790. { { 0x09ed9640, 0xf020, 0x400a, { 0xac, 0xd8, 0xd7, 0xd8, 0x67, 0xdf, 0xd9, 0xc2, } } /*09ed9640-f020-400a-acd8-d7d867dfd9c2*/, "Office Mondo 2010", EPID_OFFICE2010, APP_ID_OFFICE2010, KMS_ID_OFFICE2010 },
  2791. { { 0xef3d4e49, 0xa53d, 0x4d81, { 0xa2, 0xb1, 0x2c, 0xa6, 0xc2, 0x55, 0x6b, 0x2c, } } /*ef3d4e49-a53d-4d81-a2b1-2ca6c2556b2c*/, "Office Mondo 2010", EPID_OFFICE2010, APP_ID_OFFICE2010, KMS_ID_OFFICE2010 },
  2792. { { 0xab586f5c, 0x5256, 0x4632, { 0x96, 0x2f, 0xfe, 0xfd, 0x8b, 0x49, 0xe6, 0xf4, } } /*ab586f5c-5256-4632-962f-fefd8b49e6f4*/, "Office OneNote 2010", EPID_OFFICE2010, APP_ID_OFFICE2010, KMS_ID_OFFICE2010 },
  2793. { { 0xecb7c192, 0x73ab, 0x4ded, { 0xac, 0xf4, 0x23, 0x99, 0xb0, 0x95, 0xd0, 0xcc, } } /*ecb7c192-73ab-4ded-acf4-2399b095d0cc*/, "Office OutLook 2010", EPID_OFFICE2010, APP_ID_OFFICE2010, KMS_ID_OFFICE2010 },
  2794. { { 0x45593b1d, 0xdfb1, 0x4e91, { 0xbb, 0xfb, 0x2d, 0x5d, 0x0c, 0xe2, 0x22, 0x7a, } } /*45593b1d-dfb1-4e91-bbfb-2d5d0ce2227a*/, "Office PowerPoint 2010", EPID_OFFICE2010, APP_ID_OFFICE2010, KMS_ID_OFFICE2010 },
  2795. { { 0xdf133ff7, 0xbf14, 0x4f95, { 0xaf, 0xe3, 0x7b, 0x48, 0xe7, 0xe3, 0x31, 0xef, } } /*df133ff7-bf14-4f95-afe3-7b48e7e331ef*/, "Office Project Pro 2010", EPID_OFFICE2010, APP_ID_OFFICE2010, KMS_ID_OFFICE2010 },
  2796. { { 0x5dc7bf61, 0x5ec9, 0x4996, { 0x9c, 0xcb, 0xdf, 0x80, 0x6a, 0x2d, 0x0e, 0xfe, } } /*5dc7bf61-5ec9-4996-9ccb-df806a2d0efe*/, "Office Project Standard 2010", EPID_OFFICE2010, APP_ID_OFFICE2010, KMS_ID_OFFICE2010 },
  2797. { { 0xb50c4f75, 0x599b, 0x43e8, { 0x8d, 0xcd, 0x10, 0x81, 0xa7, 0x96, 0x72, 0x41, } } /*b50c4f75-599b-43e8-8dcd-1081a7967241*/, "Office Publisher 2010", EPID_OFFICE2010, APP_ID_OFFICE2010, KMS_ID_OFFICE2010 },
  2798. { { 0x92236105, 0xbb67, 0x494f, { 0x94, 0xc7, 0x7f, 0x7a, 0x60, 0x79, 0x29, 0xbd, } } /*92236105-bb67-494f-94c7-7f7a607929bd*/, "Office Visio Premium 2010", EPID_OFFICE2010, APP_ID_OFFICE2010, KMS_ID_OFFICE2010 },
  2799. { { 0xe558389c, 0x83c3, 0x4b29, { 0xad, 0xfe, 0x5e, 0x4d, 0x7f, 0x46, 0xc3, 0x58, } } /*e558389c-83c3-4b29-adfe-5e4d7f46c358*/, "Office Visio Pro 2010", EPID_OFFICE2010, APP_ID_OFFICE2010, KMS_ID_OFFICE2010 },
  2800. { { 0x9ed833ff, 0x4f92, 0x4f36, { 0xb3, 0x70, 0x86, 0x83, 0xa4, 0xf1, 0x32, 0x75, } } /*9ed833ff-4f92-4f36-b370-8683a4f13275*/, "Office Visio Standard 2010", EPID_OFFICE2010, APP_ID_OFFICE2010, KMS_ID_OFFICE2010 },
  2801. { { 0x2d0882e7, 0xa4e7, 0x423b, { 0x8c, 0xcc, 0x70, 0xd9, 0x1e, 0x01, 0x58, 0xb1, } } /*2d0882e7-a4e7-423b-8ccc-70d91e0158b1*/, "Office Word 2010", EPID_OFFICE2010, APP_ID_OFFICE2010, KMS_ID_OFFICE2010 },
  2802. { { 0x6f327760, 0x8c5c, 0x417c, { 0x9b, 0x61, 0x83, 0x6a, 0x98, 0x28, 0x7e, 0x0c, } } /*6f327760-8c5c-417c-9b61-836a98287e0c*/, "Office Professional Plus 2010", EPID_OFFICE2010, APP_ID_OFFICE2010, KMS_ID_OFFICE2010 },
  2803. { { 0x9da2a678, 0xfb6b, 0x4e67, { 0xab, 0x84, 0x60, 0xdd, 0x6a, 0x9c, 0x81, 0x9a, } } /*9da2a678-fb6b-4e67-ab84-60dd6a9c819a*/, "Office Standard 2010", EPID_OFFICE2010, APP_ID_OFFICE2010, KMS_ID_OFFICE2010 },
  2804. { { 0xea509e87, 0x07a1, 0x4a45, { 0x9e, 0xdc, 0xeb, 0xa5, 0xa3, 0x9f, 0x36, 0xaf, } } /*ea509e87-07a1-4a45-9edc-eba5a39f36af*/, "Office Small Business Basics 2010", EPID_OFFICE2010, APP_ID_OFFICE2010, KMS_ID_OFFICE2010 },
  2805. // Office 2013
  2806. { { 0x6ee7622c, 0x18d8, 0x4005, { 0x9f, 0xb7, 0x92, 0xdb, 0x64, 0x4a, 0x27, 0x9b, } } /*6ee7622c-18d8-4005-9fb7-92db644a279b*/, "Office Access 2013", EPID_OFFICE2013, APP_ID_OFFICE2013, KMS_ID_OFFICE2013 },
  2807. { { 0xf7461d52, 0x7c2b, 0x43b2, { 0x87, 0x44, 0xea, 0x95, 0x8e, 0x0b, 0xd0, 0x9a, } } /*f7461d52-7c2b-43b2-8744-ea958e0bd09a*/, "Office Excel 2013", EPID_OFFICE2013, APP_ID_OFFICE2013, KMS_ID_OFFICE2013 },
  2808. { { 0xa30b8040, 0xd68a, 0x423f, { 0xb0, 0xb5, 0x9c, 0xe2, 0x92, 0xea, 0x5a, 0x8f, } } /*a30b8040-d68a-423f-b0b5-9ce292ea5a8f*/, "Office InfoPath 2013", EPID_OFFICE2013, APP_ID_OFFICE2013, KMS_ID_OFFICE2013 },
  2809. { { 0x1b9f11e3, 0xc85c, 0x4e1b, { 0xbb, 0x29, 0x87, 0x9a, 0xd2, 0xc9, 0x09, 0xe3, } } /*1b9f11e3-c85c-4e1b-bb29-879ad2c909e3*/, "Office Lync 2013", EPID_OFFICE2013, APP_ID_OFFICE2013, KMS_ID_OFFICE2013 },
  2810. { { 0xdc981c6b, 0xfc8e, 0x420f, { 0xaa, 0x43, 0xf8, 0xf3, 0x3e, 0x5c, 0x09, 0x23, } } /*dc981c6b-fc8e-420f-aa43-f8f33e5c0923*/, "Office Mondo 2013", EPID_OFFICE2013, APP_ID_OFFICE2013, KMS_ID_OFFICE2013 },
  2811. { { 0xefe1f3e6, 0xaea2, 0x4144, { 0xa2, 0x08, 0x32, 0xaa, 0x87, 0x2b, 0x65, 0x45, } } /*efe1f3e6-aea2-4144-a208-32aa872b6545*/, "Office OneNote 2013", EPID_OFFICE2013, APP_ID_OFFICE2013, KMS_ID_OFFICE2013 },
  2812. { { 0x771c3afa, 0x50c5, 0x443f, { 0xb1, 0x51, 0xff, 0x25, 0x46, 0xd8, 0x63, 0xa0, } } /*771c3afa-50c5-443f-b151-ff2546d863a0*/, "Office OutLook 2013", EPID_OFFICE2013, APP_ID_OFFICE2013, KMS_ID_OFFICE2013 },
  2813. { { 0x8c762649, 0x97d1, 0x4953, { 0xad, 0x27, 0xb7, 0xe2, 0xc2, 0x5b, 0x97, 0x2e, } } /*8c762649-97d1-4953-ad27-b7e2c25b972e*/, "Office PowerPoint 2013", EPID_OFFICE2013, APP_ID_OFFICE2013, KMS_ID_OFFICE2013 },
  2814. { { 0x4a5d124a, 0xe620, 0x44ba, { 0xb6, 0xff, 0x65, 0x89, 0x61, 0xb3, 0x3b, 0x9a, } } /*4a5d124a-e620-44ba-b6ff-658961b33b9a*/, "Office Project Pro 2013", EPID_OFFICE2013, APP_ID_OFFICE2013, KMS_ID_OFFICE2013 },
  2815. { { 0x427a28d1, 0xd17c, 0x4abf, { 0xb7, 0x17, 0x32, 0xc7, 0x80, 0xba, 0x6f, 0x07, } } /*427a28d1-d17c-4abf-b717-32c780ba6f07*/, "Office Project Standard 2013", EPID_OFFICE2013, APP_ID_OFFICE2013, KMS_ID_OFFICE2013 },
  2816. { { 0x00c79ff1, 0x6850, 0x443d, { 0xbf, 0x61, 0x71, 0xcd, 0xe0, 0xde, 0x30, 0x5f, } } /*00c79ff1-6850-443d-bf61-71cde0de305f*/, "Office Publisher 2013", EPID_OFFICE2013, APP_ID_OFFICE2013, KMS_ID_OFFICE2013 },
  2817. { { 0xac4efaf0, 0xf81f, 0x4f61, { 0xbd, 0xf7, 0xea, 0x32, 0xb0, 0x2a, 0xb1, 0x17, } } /*ac4efaf0-f81f-4f61-bdf7-ea32b02ab117*/, "Office Visio Standard 2013", EPID_OFFICE2013, APP_ID_OFFICE2013, KMS_ID_OFFICE2013 },
  2818. { { 0xe13ac10e, 0x75d0, 0x4aff, { 0xa0, 0xcd, 0x76, 0x49, 0x82, 0xcf, 0x54, 0x1c, } } /*e13ac10e-75d0-4aff-a0cd-764982cf541c*/, "Office Visio Pro 2013", EPID_OFFICE2013, APP_ID_OFFICE2013, KMS_ID_OFFICE2013 },
  2819. { { 0xd9f5b1c6, 0x5386, 0x495a, { 0x88, 0xf9, 0x9a, 0xd6, 0xb4, 0x1a, 0xc9, 0xb3, } } /*d9f5b1c6-5386-495a-88f9-9ad6b41ac9b3*/, "Office Word 2013", EPID_OFFICE2013, APP_ID_OFFICE2013, KMS_ID_OFFICE2013 },
  2820. { { 0xb322da9c, 0xa2e2, 0x4058, { 0x9e, 0x4e, 0xf5, 0x9a, 0x69, 0x70, 0xbd, 0x69, } } /*b322da9c-a2e2-4058-9e4e-f59a6970bd69*/, "Office Professional Plus 2013", EPID_OFFICE2013, APP_ID_OFFICE2013, KMS_ID_OFFICE2013 },
  2821. { { 0xb13afb38, 0xcd79, 0x4ae5, { 0x9f, 0x7f, 0xee, 0xd0, 0x58, 0xd7, 0x50, 0xca, } } /*b13afb38-cd79-4ae5-9f7f-eed058d750ca*/, "Office Standard 2013", EPID_OFFICE2013, APP_ID_OFFICE2013, KMS_ID_OFFICE2013 },
  2822. // Office 2016
  2823. { { 0xd450596f, 0x894d, 0x49e0, { 0x96, 0x6a, 0xfd, 0x39, 0xed, 0x4c, 0x4c, 0x64, } } /*d450596f-894d-49e0-966a-fd39ed4c4c64*/, "Office Professional Plus 2016", EPID_OFFICE2013, APP_ID_OFFICE2013, KMS_ID_OFFICE2016 },
  2824. { { 0x4f414197, 0x0fc2, 0x4c01, { 0xb6, 0x8a, 0x86, 0xcb, 0xb9, 0xac, 0x25, 0x4c, } } /*4f414197-0fc2-4c01-b68a-86cbb9ac254c*/, "Office Project Pro 2016", EPID_OFFICE2013, APP_ID_OFFICE2013, KMS_ID_OFFICE2016 },
  2825. { { 0x6bf301c1, 0xb94a, 0x43e9, { 0xba, 0x31, 0xd4, 0x94, 0x59, 0x8c, 0x47, 0xfb, } } /*6bf301c1-b94a-43e9-ba31-d494598c47fb*/, "Office Visio Pro 2016", EPID_OFFICE2013, APP_ID_OFFICE2013, KMS_ID_OFFICE2016 },
  2826. { { 0x041a06cb, 0xc5b8, 0x4772, { 0x80, 0x9f, 0x41, 0x6d, 0x03, 0xd1, 0x66, 0x54, } } /*041a06cb-c5b8-4772-809f-416d03d16654*/, "Office Publisher 2016", EPID_OFFICE2013, APP_ID_OFFICE2013, KMS_ID_OFFICE2016 },
  2827. { { 0x67c0fc0c, 0xdeba, 0x401b, { 0xbf, 0x8b, 0x9c, 0x8a, 0xd8, 0x39, 0x58, 0x04, } } /*67c0fc0c-deba-401b-bf8b-9c8ad8395804*/, "Office Access 2016", EPID_OFFICE2013, APP_ID_OFFICE2013, KMS_ID_OFFICE2016 },
  2828. { { 0x83e04ee1, 0xfa8d, 0x436d, { 0x89, 0x94, 0xd3, 0x1a, 0x86, 0x2c, 0xab, 0x77, } } /*83e04ee1-fa8d-436d-8994-d31a862cab77*/, "Office Skype for Business 2016", EPID_OFFICE2013, APP_ID_OFFICE2013, KMS_ID_OFFICE2016 },
  2829. { { 0x9caabccb, 0x61b1, 0x4b4b, { 0x8b, 0xec, 0xd1, 0x0a, 0x3c, 0x3a, 0xc2, 0xce, } } /*9caabccb-61b1-4b4b-8bec-d10a3c3ac2ce*/, "Office Mondo 2016", EPID_OFFICE2013, APP_ID_OFFICE2013, KMS_ID_OFFICE2016 },
  2830. { { 0xaa2a7821, 0x1827, 0x4c2c, { 0x8f, 0x1d, 0x45, 0x13, 0xa3, 0x4d, 0xda, 0x97, } } /*aa2a7821-1827-4c2c-8f1d-4513a34dda97*/, "Office Visio Standard 2016", EPID_OFFICE2013, APP_ID_OFFICE2013, KMS_ID_OFFICE2016 },
  2831. { { 0xbb11badf, 0xd8aa, 0x470e, { 0x93, 0x11, 0x20, 0xea, 0xf8, 0x0f, 0xe5, 0xcc, } } /*bb11badf-d8aa-470e-9311-20eaf80fe5cc*/, "Office Word 2016", EPID_OFFICE2013, APP_ID_OFFICE2013, KMS_ID_OFFICE2016 },
  2832. { { 0xc3e65d36, 0x141f, 0x4d2f, { 0xa3, 0x03, 0xa8, 0x42, 0xee, 0x75, 0x6a, 0x29, } } /*c3e65d36-141f-4d2f-a303-a842ee756a29*/, "Office Excel 2016", EPID_OFFICE2013, APP_ID_OFFICE2013, KMS_ID_OFFICE2016 },
  2833. { { 0xd70b1bba, 0xb893, 0x4544, { 0x96, 0xe2, 0xb7, 0xa3, 0x18, 0x09, 0x1c, 0x33, } } /*d70b1bba-b893-4544-96e2-b7a318091c33*/, "Office Powerpoint 2016", EPID_OFFICE2013, APP_ID_OFFICE2013, KMS_ID_OFFICE2016 },
  2834. { { 0xd8cace59, 0x33d2, 0x4ac7, { 0x9b, 0x1b, 0x9b, 0x72, 0x33, 0x9c, 0x51, 0xc8, } } /*d8cace59-33d2-4ac7-9b1b-9b72339c51c8*/, "Office OneNote 2016", EPID_OFFICE2013, APP_ID_OFFICE2013, KMS_ID_OFFICE2016 },
  2835. { { 0xda7ddabc, 0x3fbe, 0x4447, { 0x9e, 0x01, 0x6a, 0xb7, 0x44, 0x0b, 0x4c, 0xd4, } } /*da7ddabc-3fbe-4447-9e01-6ab7440b4cd4*/, "Office Project Standard 2016", EPID_OFFICE2013, APP_ID_OFFICE2013, KMS_ID_OFFICE2016 },
  2836. { { 0xdedfa23d, 0x6ed1, 0x45a6, { 0x85, 0xdc, 0x63, 0xca, 0xe0, 0x54, 0x6d, 0xe6, } } /*dedfa23d-6ed1-45a6-85dc-63cae0546de6*/, "Office Standard 2016", EPID_OFFICE2013, APP_ID_OFFICE2013, KMS_ID_OFFICE2016 },
  2837. { { 0xe914ea6e, 0xa5fa, 0x4439, { 0xa3, 0x94, 0xa9, 0xbb, 0x32, 0x93, 0xca, 0x09, } } /*e914ea6e-a5fa-4439-a394-a9bb3293ca09*/, "Office Mondo R 2016", EPID_OFFICE2013, APP_ID_OFFICE2013, KMS_ID_OFFICE2016 },
  2838. { { 0xec9d9265, 0x9d1e, 0x4ed0, { 0x83, 0x8a, 0xcd, 0xc2, 0x0f, 0x25, 0x51, 0xa1, } } /*ec9d9265-9d1e-4ed0-838a-cdc20f2551a1*/, "Office Outlook 2016", EPID_OFFICE2013, APP_ID_OFFICE2013, KMS_ID_OFFICE2016 },
  2839. // End marker (necessity should be removed when time permits)
  2840. { { 0x00000000, 0x0000, 0x0000, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }, NULL, NULL, 0, 0 }
  2841. };
  2842. // necessary because other .c files cannot access _countof()
  2843. __pure ProdListIndex_t getExtendedProductListSize(void)
  2844. {
  2845. return _countof(ExtendedProductList) - 1;
  2846. }
  2847. __pure ProdListIndex_t getAppListSize(void)
  2848. {
  2849. return _countof(AppList);
  2850. }
  2851. #endif
  2852. #ifndef NO_RANDOM_EPID
  2853. // HostType and OSBuild
  2854. static const struct KMSHostOS { uint16_t Type; uint16_t Build; } HostOS[] =
  2855. {
  2856. { 55041, 6002 }, // Windows Server 2008 SP2
  2857. { 55041, 7601 }, // Windows Server 2008 R2 SP1
  2858. { 5426, 9200 }, // Windows Server 2012
  2859. { 6401, 9600 }, // Windows Server 2012 R2
  2860. { 3612, 10240}, // Windows Server 2016
  2861. };
  2862. // GroupID and PIDRange
  2863. static const struct PKEYCONFIG { uint16_t GroupID; uint32_t RangeMin; uint32_t RangeMax; } pkeyconfig[] = {
  2864. { 206, 152000000, 191999999 }, // Windows Server 2012 KMS Host pkeyconfig
  2865. { 206, 271000000, 310999999 }, // Windows Server 2012 R2 KMS Host pkeyconfig
  2866. { 96, 199000000, 217999999 }, // Office2010 KMS Host pkeyconfig
  2867. { 206, 234000000, 255999999 }, // Office2013 KMS Host pkeyconfig
  2868. };
  2869. // Valid language identifiers to be used in the ePID
  2870. static const uint16_t LcidList[] = {
  2871. 1078, 1052, 1025, 2049, 3073, 4097, 5121, 6145, 7169, 8193, 9217, 10241, 11265, 12289, 13313, 14337, 15361, 16385,
  2872. 1067, 1068, 2092, 1069, 1059, 1093, 5146, 1026, 1027, 1028, 2052, 3076, 4100, 5124, 1050, 4122, 1029, 1030, 1125, 1043, 2067,
  2873. 1033, 2057, 3081, 4105, 5129, 6153, 7177, 8201, 9225, 10249, 11273, 12297, 13321, 1061, 1080, 1065, 1035, 1036, 2060,
  2874. 3084, 4108, 5132, 6156, 1079, 1110, 1031, 2055, 3079, 4103, 5127, 1032, 1095, 1037, 1081, 1038, 1039, 1057, 1040, 2064, 1041, 1099,
  2875. 1087, 1111, 1042, 1088, 1062, 1063, 1071, 1086, 2110, 1100, 1082, 1153, 1102, 1104, 1044, 2068, 1045, 1046, 2070,
  2876. 1094, 1131, 2155, 3179, 1048, 1049, 9275, 4155, 5179, 3131, 1083, 2107, 8251, 6203, 7227, 1103, 2074, 6170, 3098,
  2877. 7194, 1051, 1060, 1034, 2058, 3082, 4106, 5130, 6154, 7178, 8202, 9226, 10250, 11274, 12298, 13322, 14346, 15370, 16394,
  2878. 17418, 18442, 19466, 20490, 1089, 1053, 2077, 1114, 1097, 1092, 1098, 1054, 1074, 1058, 1056, 1091, 2115, 1066, 1106, 1076, 1077
  2879. };
  2880. #ifdef _PEDANTIC
  2881. uint16_t IsValidLcid(const uint16_t Lcid)
  2882. {
  2883. uint16_t i;
  2884. for (i = 0; i < _countof(LcidList); i++)
  2885. {
  2886. if (Lcid == LcidList[i]) return Lcid;
  2887. }
  2888. return 0;
  2889. }
  2890. #endif // _PEDANTIC
  2891. #endif // NO_RANDOM_EPID
  2892. // Unix time is seconds from 1970-01-01. Should be 64 bits to avoid Year 2035 overflow bug.
  2893. // FILETIME is 100 nanoseconds from 1601-01-01. Must be 64 bits.
  2894. void getUnixTimeAsFileTime(FILETIME *const ts)
  2895. {
  2896. int64_t unixtime = (int64_t)time(NULL);
  2897. int64_t *filetime = (int64_t*)ts;
  2898. *filetime = LE64( (unixtime + 11644473600LL) * 10000000LL );
  2899. }
  2900. __pure int64_t fileTimeToUnixTime(const FILETIME *const ts)
  2901. {
  2902. return LE64( *((const int64_t *const)ts) ) / 10000000LL - 11644473600LL;
  2903. }
  2904. /*
  2905. * Get's a product name with a GUID in host-endian order.
  2906. * List can be any list defined above.
  2907. */
  2908. const char* getProductNameHE(const GUID *const guid, const KmsIdList *const List, ProdListIndex_t *const i)
  2909. {
  2910. for (*i = 0; List[*i].name != NULL; (*i)++)
  2911. {
  2912. if (IsEqualGUID(guid, &List[*i].guid))
  2913. return List[*i].name;
  2914. }
  2915. return "Unknown";
  2916. }
  2917. /*
  2918. * same as getProductnameHE except GUID is in little-endian (network) order
  2919. */
  2920. const char* getProductNameLE(const GUID *const guid, const KmsIdList *const List, ProdListIndex_t *const i)
  2921. {
  2922. #if __BYTE_ORDER != __LITTLE_ENDIAN
  2923. GUID HeGUID;
  2924. LEGUID(&HeGUID, guid);
  2925. return getProductNameHE(&HeGUID, List, i);
  2926. #else
  2927. return getProductNameHE(guid, List, i);
  2928. #endif
  2929. }
  2930. #ifndef NO_RANDOM_EPID
  2931. // formats an int with a fixed number of digits with leading zeros (helper for ePID generation)
  2932. static char* itoc(char *const c, const int i, uint_fast8_t digits)
  2933. {
  2934. char formatString[8];
  2935. if (digits > 9) digits = 0;
  2936. strcpy(formatString,"%");
  2937. if (digits)
  2938. {
  2939. formatString[1] = '0';
  2940. formatString[2] = digits | 0x30;
  2941. formatString[3] = 0;
  2942. }
  2943. strcat(formatString, "u");
  2944. sprintf(c, formatString, i);
  2945. return c;
  2946. }
  2947. static int getRandomServerType()
  2948. {
  2949. # ifndef USE_MSRPC
  2950. if (!UseRpcBTFN)
  2951. # endif // USE_MSRPC
  2952. {
  2953. // This isn't possible at all, e.g. KMS host on XP
  2954. return rand() % (int)_countof(HostOS);
  2955. }
  2956. # ifndef USE_MSRPC
  2957. else
  2958. {
  2959. // return 9200/9600/10240 if NDR64 is in use, otherwise 6002/7601
  2960. if (UseRpcNDR64) return (rand() % 3) + 2;
  2961. return (rand() % 2);
  2962. }
  2963. # endif // USE_MSRPC
  2964. }
  2965. /*
  2966. * Generates a random ePID
  2967. */
  2968. static void generateRandomPid(const int index, char *const szPid, int serverType, int16_t lang)
  2969. {
  2970. int clientApp;
  2971. char numberBuffer[12];
  2972. if (serverType < 0 || serverType >= (int)_countof(HostOS))
  2973. {
  2974. serverType = getRandomServerType();
  2975. }
  2976. strcpy(szPid, itoc(numberBuffer, HostOS[serverType].Type, 5));
  2977. strcat(szPid, "-");
  2978. if (index == 2)
  2979. clientApp = 3;
  2980. else if (index == 1)
  2981. clientApp = 2;
  2982. else
  2983. clientApp = serverType == 3 /*change if HostOS changes*/ ? 1 : 0;
  2984. strcat(szPid, itoc(numberBuffer, pkeyconfig[clientApp].GroupID, 5));
  2985. strcat(szPid, "-");
  2986. int keyId = (rand32() % (pkeyconfig[clientApp].RangeMax - pkeyconfig[clientApp].RangeMin)) + pkeyconfig[clientApp].RangeMin;
  2987. strcat(szPid, itoc(numberBuffer, keyId / 1000000, 3));
  2988. strcat(szPid, "-");
  2989. strcat(szPid, itoc(numberBuffer, keyId % 1000000, 6));
  2990. strcat(szPid, "-03-");
  2991. if (lang < 0) lang = LcidList[rand() % _countof(LcidList)];
  2992. strcat(szPid, itoc(numberBuffer, lang, 0));
  2993. strcat(szPid, "-");
  2994. strcat(szPid, itoc(numberBuffer, HostOS[serverType].Build, 0));
  2995. strcat(szPid, ".0000-");
  2996. # define minTime ((time_t)1436958000) // Release Date Windows 10 RTM Escrow
  2997. time_t maxTime, kmsTime;
  2998. time(&maxTime);
  2999. if (maxTime < minTime) // Just in case the system time is < 07/15/2015 1:00 pm
  3000. maxTime = (time_t)BUILD_TIME;
  3001. kmsTime = (rand32() % (maxTime - minTime)) + minTime;
  3002. # undef minTime
  3003. struct tm *pidTime;
  3004. pidTime = gmtime(&kmsTime);
  3005. strcat(szPid, itoc(numberBuffer, pidTime->tm_yday, 3));
  3006. strcat(szPid, itoc(numberBuffer, pidTime->tm_year + 1900, 4));
  3007. }
  3008. /*
  3009. * Generates random ePIDs and stores them if not already read from ini file.
  3010. * For use with randomization level 1
  3011. */
  3012. void randomPidInit()
  3013. {
  3014. ProdListIndex_t i;
  3015. int serverType = getRandomServerType();
  3016. int16_t lang = Lcid ? Lcid : LcidList[rand() % _countof(LcidList)];
  3017. for (i = 0; i < _countof(AppList) - 1; i++)
  3018. {
  3019. if (KmsResponseParameters[i].Epid) continue;
  3020. char Epid[PID_BUFFER_SIZE];
  3021. generateRandomPid(i, Epid, serverType, lang);
  3022. KmsResponseParameters[i].Epid = (const char*)vlmcsd_malloc(strlen(Epid) + 1);
  3023. strcpy((char*)KmsResponseParameters[i].Epid, Epid);
  3024. #ifndef NO_LOG
  3025. KmsResponseParameters[i].EpidSource = "randomized at program start";
  3026. #endif // NO_LOG
  3027. }
  3028. }
  3029. #endif // NO_RANDOM_EPID
  3030. #ifndef NO_LOG
  3031. /*
  3032. * Logs a Request
  3033. */
  3034. static void logRequest(const REQUEST *const baseRequest)
  3035. {
  3036. const char *productName;
  3037. char clientname[64];
  3038. ProdListIndex_t index;
  3039. #ifndef NO_EXTENDED_PRODUCT_LIST
  3040. productName = getProductNameLE(&baseRequest->ActID, ExtendedProductList, &index);
  3041. if (++index >= (int)_countof(ExtendedProductList))
  3042. #endif // NO_EXTENDED_PRODUCT_LIST
  3043. {
  3044. #ifndef NO_BASIC_PRODUCT_LIST
  3045. productName = getProductNameLE(&baseRequest->KMSID, ProductList, &index);
  3046. if (++index >= (int)_countof(ProductList))
  3047. #endif // NO_BASIC_PRODUCT_LIST
  3048. {
  3049. productName = getProductNameLE(&baseRequest->AppID, AppList, &index);
  3050. }
  3051. }
  3052. #ifndef NO_VERBOSE_LOG
  3053. if (logverbose)
  3054. {
  3055. logger("<<< Incoming KMS request\n");
  3056. logRequestVerbose(baseRequest, &logger);
  3057. }
  3058. else
  3059. {
  3060. #endif // NO_VERBOSE_LOG
  3061. ucs2_to_utf8(baseRequest->WorkstationName, clientname, 64, 64);
  3062. logger("KMS v%i.%i request from %s for %s\n", LE16(baseRequest->MajorVer), LE16(baseRequest->MinorVer), clientname, productName);
  3063. #ifndef NO_VERBOSE_LOG
  3064. }
  3065. #endif // NO_VERBOSE_LOG
  3066. }
  3067. #endif // NO_LOG
  3068. /*
  3069. * Converts a utf-8 ePID string to UCS-2 and writes it to a RESPONSE struct
  3070. */
  3071. static void getEpidFromString(RESPONSE *const Response, const char *const pid)
  3072. {
  3073. size_t length = utf8_to_ucs2(Response->KmsPID, pid, PID_BUFFER_SIZE, PID_BUFFER_SIZE * 3);
  3074. Response->PIDSize = LE32(((unsigned int )length + 1) << 1);
  3075. }
  3076. /*
  3077. * get ePID from appropriate source
  3078. */
  3079. static void getEpid(RESPONSE *const baseResponse, const char** EpidSource, const ProdListIndex_t index, BYTE *const HwId)
  3080. {
  3081. const char* pid;
  3082. if (KmsResponseParameters[index].Epid == NULL)
  3083. {
  3084. #ifndef NO_RANDOM_EPID
  3085. if (RandomizationLevel == 2)
  3086. {
  3087. char szPid[PID_BUFFER_SIZE];
  3088. generateRandomPid(index, szPid, -1, Lcid ? Lcid : -1);
  3089. pid = szPid;
  3090. #ifndef NO_LOG
  3091. *EpidSource = "randomized on every request";
  3092. #endif // NO_LOG
  3093. }
  3094. else
  3095. #endif // NO_RANDOM_EPID
  3096. {
  3097. pid = AppList[index].pid;
  3098. #ifndef NO_LOG
  3099. *EpidSource = "vlmcsd default";
  3100. #endif // NO_LOG
  3101. }
  3102. }
  3103. else
  3104. {
  3105. pid = KmsResponseParameters[index].Epid;
  3106. if (HwId && KmsResponseParameters[index].HwId != NULL)
  3107. memcpy(HwId, KmsResponseParameters[index].HwId, sizeof(((RESPONSE_V6 *)0)->HwId));
  3108. #ifndef NO_LOG
  3109. *EpidSource = KmsResponseParameters[index].EpidSource;
  3110. #endif // NO_LOG
  3111. }
  3112. getEpidFromString(baseResponse, pid);
  3113. }
  3114. #if !defined(NO_LOG) && defined(_PEDANTIC)
  3115. static BOOL CheckVersion4Uuid(const GUID *const guid, const char *const szGuidName)
  3116. {
  3117. if (LE16(guid->Data3) >> 12 != 4 || guid->Data4[0] >> 6 != 2)
  3118. {
  3119. logger("Warning: %s does not conform to version 4 UUID according to RFC 4122\n", szGuidName);
  3120. return FALSE;
  3121. }
  3122. return TRUE;
  3123. }
  3124. static void CheckRequest(const REQUEST *const Request)
  3125. {
  3126. CheckVersion4Uuid(&Request->CMID, "Client machine ID");
  3127. CheckVersion4Uuid(&Request->AppID, "Application ID");
  3128. CheckVersion4Uuid(&Request->KMSID, "Server SKU ID");
  3129. CheckVersion4Uuid(&Request->ActID, "Client SKU ID");
  3130. if (LE32(Request->IsClientVM) > 1)
  3131. logger("Warning: Virtual Machine field in request must be 0 or 1 but is %u\n", LE32(Request->IsClientVM));
  3132. if (LE32(Request->LicenseStatus) > 6 )
  3133. logger("Warning: License status must be between 0 and 6 but is %u\n", LE32(Request->LicenseStatus));
  3134. }
  3135. #endif // !defined(NO_LOG) && defined(_PEDANTIC)
  3136. #ifndef NO_LOG
  3137. /*
  3138. * Logs the Response
  3139. */
  3140. static void logResponse(const RESPONSE *const baseResponse, const BYTE *const hwId, const char *const EpidSource)
  3141. {
  3142. char utf8pid[PID_BUFFER_SIZE * 3];
  3143. ucs2_to_utf8(baseResponse->KmsPID, utf8pid, PID_BUFFER_SIZE, PID_BUFFER_SIZE * 3);
  3144. #ifndef NO_VERBOSE_LOG
  3145. if (!logverbose)
  3146. {
  3147. #endif // NO_VERBOSE_LOG
  3148. logger("Sending ePID (%s): %s\n", EpidSource, utf8pid);
  3149. #ifndef NO_VERBOSE_LOG
  3150. }
  3151. else
  3152. {
  3153. logger(">>> Sending response, ePID source = %s\n", EpidSource);
  3154. logResponseVerbose(utf8pid, hwId, baseResponse, &logger);
  3155. }
  3156. #endif // NO_VERBOSE_LOG
  3157. }
  3158. #endif
  3159. /*
  3160. * Creates the unencrypted base response
  3161. */
  3162. static BOOL __stdcall CreateResponseBaseCallback(const REQUEST *const baseRequest, RESPONSE *const baseResponse, BYTE *const hwId, const char* const ipstr)
  3163. {
  3164. const char* EpidSource;
  3165. #ifndef NO_LOG
  3166. logRequest(baseRequest);
  3167. #ifdef _PEDANTIC
  3168. CheckRequest(baseRequest);
  3169. #endif // _PEDANTIC
  3170. #endif // NO_LOG
  3171. ProdListIndex_t index;
  3172. getProductNameLE(&baseRequest->AppID, AppList, &index);
  3173. if (index >= _countof(AppList) - 1) index = 0; //default to Windows
  3174. getEpid(baseResponse, &EpidSource, index, hwId);
  3175. baseResponse->Version = baseRequest->Version;
  3176. memcpy(&baseResponse->CMID, &baseRequest->CMID, sizeof(GUID));
  3177. memcpy(&baseResponse->ClientTime, &baseRequest->ClientTime, sizeof(FILETIME));
  3178. baseResponse->Count = LE32(LE32(baseRequest->N_Policy) << 1);
  3179. baseResponse->VLActivationInterval = LE32(VLActivationInterval);
  3180. baseResponse->VLRenewalInterval = LE32(VLRenewalInterval);
  3181. #ifndef NO_LOG
  3182. logResponse(baseResponse, hwId, EpidSource);
  3183. #endif // NO_LOG
  3184. return !0;
  3185. }
  3186. RequestCallback_t CreateResponseBase = &CreateResponseBaseCallback;
  3187. ////TODO: Move to helpers.c
  3188. void get16RandomBytes(void* ptr)
  3189. {
  3190. int i;
  3191. for (i = 0; i < 4; i++) ((DWORD*)ptr)[i] = rand32();
  3192. }
  3193. /*
  3194. * Creates v4 response
  3195. */
  3196. size_t CreateResponseV4(REQUEST_V4 *const request_v4, BYTE *const responseBuffer, const char* const ipstr)
  3197. {
  3198. RESPONSE_V4* Response = (RESPONSE_V4*)responseBuffer;
  3199. if ( !CreateResponseBase(&request_v4->RequestBase, &Response->ResponseBase, NULL, ipstr) ) return 0;
  3200. DWORD pidSize = LE32(Response->ResponseBase.PIDSize);
  3201. BYTE* postEpidPtr = responseBuffer + V4_PRE_EPID_SIZE + pidSize;
  3202. memmove(postEpidPtr, &Response->ResponseBase.CMID, V4_POST_EPID_SIZE);
  3203. size_t encryptSize = V4_PRE_EPID_SIZE + V4_POST_EPID_SIZE + pidSize;
  3204. AesCmacV4(responseBuffer, encryptSize, responseBuffer + encryptSize);
  3205. return encryptSize + sizeof(Response->MAC);
  3206. }
  3207. /*
  3208. // Workaround for buggy GCC 4.2/4.3
  3209. #if defined(__GNUC__) && (__GNUC__ == 4 && __GNUC_MINOR__ < 4)
  3210. __attribute__((noinline))
  3211. #endif
  3212. __pure static uint64_t TimestampInterval(void *ts)
  3213. {
  3214. return ( GET_UA64LE(ts) / TIME_C1 ) * TIME_C2 + TIME_C3;
  3215. }*/
  3216. /*
  3217. * Creates the HMAC for v6
  3218. */
  3219. static int_fast8_t CreateV6Hmac(BYTE *const encrypt_start, const size_t encryptSize, int_fast8_t tolerance)
  3220. {
  3221. BYTE hash[32];
  3222. # define halfHashSize (sizeof(hash) >> 1)
  3223. uint64_t timeSlot;
  3224. BYTE *responseEnd = encrypt_start + encryptSize;
  3225. // This is the time from the response
  3226. FILETIME* ft = (FILETIME*)(responseEnd - V6_POST_EPID_SIZE + sizeof(((RESPONSE*)0)->CMID));
  3227. // Generate a time slot that changes every 4.11 hours.
  3228. // Request and repsonse time must match +/- 1 slot.
  3229. // When generating a response tolerance must be 0.
  3230. // If verifying the hash, try tolerance -1, 0 and +1. One of them must match.
  3231. timeSlot = LE64( (GET_UA64LE(ft) / TIME_C1 * TIME_C2 + TIME_C3) + (tolerance * TIME_C1) );
  3232. // The time slot is hashed with SHA256 so it is not so obvious that it is time
  3233. Sha256((BYTE*) &timeSlot, sizeof(timeSlot), hash);
  3234. // The last 16 bytes of the hashed time slot are the actual HMAC key
  3235. if (!Sha256Hmac
  3236. (
  3237. hash + halfHashSize, // Use last 16 bytes of SHA256 as HMAC key
  3238. encrypt_start, // hash only the encrypted part of the v6 response
  3239. encryptSize - sizeof(((RESPONSE_V6*)0)->HMAC), // encryptSize minus the HMAC itself
  3240. hash // use same buffer for resulting hash where the key came from
  3241. ))
  3242. {
  3243. return FALSE;
  3244. }
  3245. memcpy(responseEnd - sizeof(((RESPONSE_V6*)0)->HMAC), hash + halfHashSize, halfHashSize);
  3246. return TRUE;
  3247. # undef halfHashSize
  3248. }
  3249. /*
  3250. * Creates v5 or v6 response
  3251. */
  3252. size_t CreateResponseV6(REQUEST_V6 *restrict request_v6, BYTE *const responseBuffer, const char* const ipstr)
  3253. {
  3254. // The response will be created in a fixed sized struct to
  3255. // avoid unaligned access macros and packed structs on RISC systems
  3256. // which largely increase code size.
  3257. //
  3258. // The fixed sized struct with 64 WCHARs for the ePID will be converted
  3259. // to a variable sized struct later and requires unaligned access macros.
  3260. RESPONSE_V6* Response = (RESPONSE_V6*)responseBuffer;
  3261. RESPONSE* baseResponse = &Response->ResponseBase;
  3262. #ifdef _DEBUG
  3263. RESPONSE_V6_DEBUG* xxx = (RESPONSE_V6_DEBUG*)responseBuffer;
  3264. #endif
  3265. static const BYTE DefaultHwid[8] = { HWID };
  3266. int_fast8_t v6 = LE16(request_v6->MajorVer) > 5;
  3267. AesCtx aesCtx;
  3268. AesInitKey(&aesCtx, v6 ? AesKeyV6 : AesKeyV5, v6, AES_KEY_BYTES);
  3269. AesDecryptCbc(&aesCtx, NULL, request_v6->IV, V6_DECRYPT_SIZE);
  3270. // get random salt and SHA256 it
  3271. get16RandomBytes(Response->RandomXoredIVs);
  3272. Sha256(Response->RandomXoredIVs, sizeof(Response->RandomXoredIVs), Response->Hash);
  3273. if (v6) // V6 specific stuff
  3274. {
  3275. // In v6 a random IV is generated
  3276. Response->Version = request_v6->Version;
  3277. get16RandomBytes(Response->IV);
  3278. // pre-fill with default HwId (not required for v5)
  3279. memcpy(Response->HwId, DefaultHwid, sizeof(Response->HwId));
  3280. // Just copy decrypted request IV (using Null IV) here. Note this is identical
  3281. // to XORing non-decrypted request and reponse IVs
  3282. memcpy(Response->XoredIVs, request_v6->IV, sizeof(Response->XoredIVs));
  3283. }
  3284. else // V5 specific stuff
  3285. {
  3286. // In v5 IVs of request and response must be identical (MS client checks this)
  3287. // The following memcpy copies Version and IVs at once
  3288. memcpy(Response, request_v6, V6_UNENCRYPTED_SIZE);
  3289. }
  3290. // Xor Random bytes with decrypted request IV
  3291. XorBlock(request_v6->IV, Response->RandomXoredIVs);
  3292. // Get the base response
  3293. if ( !CreateResponseBase(&request_v6->RequestBase, baseResponse, Response->HwId, ipstr) ) return 0;
  3294. // Convert the fixed sized struct into variable sized
  3295. DWORD pidSize = LE32(baseResponse->PIDSize);
  3296. BYTE* postEpidPtr = responseBuffer + V6_PRE_EPID_SIZE + pidSize;
  3297. size_t post_epid_size = v6 ? V6_POST_EPID_SIZE : V5_POST_EPID_SIZE;
  3298. memmove(postEpidPtr, &baseResponse->CMID, post_epid_size);
  3299. // number of bytes to encrypt
  3300. size_t encryptSize =
  3301. V6_PRE_EPID_SIZE
  3302. - sizeof(Response->Version)
  3303. + pidSize
  3304. + post_epid_size;
  3305. //AesDecryptBlock(&aesCtx, Response->IV);
  3306. if (v6 && !CreateV6Hmac(Response->IV, encryptSize, 0)) return 0;
  3307. // Padding auto handled by encryption func
  3308. AesEncryptCbc(&aesCtx, NULL, Response->IV, &encryptSize);
  3309. return encryptSize + sizeof(Response->Version);
  3310. }
  3311. // Create Hashed KMS Client Request Data for KMS Protocol Version 4
  3312. BYTE *CreateRequestV4(size_t *size, const REQUEST* requestBase)
  3313. {
  3314. *size = sizeof(REQUEST_V4);
  3315. // Build a proper KMS client request data
  3316. BYTE *request = (BYTE *)vlmcsd_malloc(sizeof(REQUEST_V4));
  3317. // Temporary Pointer for access to REQUEST_V4 structure
  3318. REQUEST_V4 *request_v4 = (REQUEST_V4 *)request;
  3319. // Set KMS Client Request Base
  3320. memcpy(&request_v4->RequestBase, requestBase, sizeof(REQUEST));
  3321. // Generate Hash Signature
  3322. AesCmacV4(request, sizeof(REQUEST), request_v4->MAC);
  3323. // Return Request Data
  3324. return request;
  3325. }
  3326. // Create Encrypted KMS Client Request Data for KMS Protocol Version 6
  3327. BYTE* CreateRequestV6(size_t *size, const REQUEST* requestBase)
  3328. {
  3329. *size = sizeof(REQUEST_V6);
  3330. // Temporary Pointer for access to REQUEST_V5 structure
  3331. REQUEST_V6 *request = (REQUEST_V6 *)vlmcsd_malloc(sizeof(REQUEST_V6));
  3332. // KMS Protocol Version
  3333. request->Version = requestBase->Version;
  3334. // Initialize the IV
  3335. get16RandomBytes(request->IV);
  3336. // Set KMS Client Request Base
  3337. memcpy(&request->RequestBase, requestBase, sizeof(REQUEST));
  3338. // Encrypt KMS Client Request
  3339. size_t encryptSize = sizeof(request->RequestBase);
  3340. AesCtx Ctx;
  3341. int_fast8_t v6 = LE16(request->MajorVer) > 5;
  3342. AesInitKey(&Ctx, v6 ? AesKeyV6 : AesKeyV5, v6, 16);
  3343. AesEncryptCbc(&Ctx, request->IV, (BYTE*)(&request->RequestBase), &encryptSize);
  3344. // Return Proper Request Data
  3345. return (BYTE*)request;
  3346. }
  3347. /*
  3348. * Checks whether Length of ePID is valid
  3349. */
  3350. static uint8_t checkPidLength(const RESPONSE *const responseBase)
  3351. {
  3352. unsigned int i;
  3353. if (LE32(responseBase->PIDSize) > (PID_BUFFER_SIZE << 1)) return FALSE;
  3354. if (responseBase->KmsPID[(LE32(responseBase->PIDSize) >> 1) - 1]) return FALSE;
  3355. for (i = 0; i < (LE32(responseBase->PIDSize) >> 1) - 2; i++)
  3356. {
  3357. if (!responseBase->KmsPID[i]) return FALSE;
  3358. }
  3359. return TRUE;
  3360. }
  3361. /*
  3362. * "Decrypts" a KMS v4 response. Actually just copies to a fixed size buffer
  3363. */
  3364. RESPONSE_RESULT DecryptResponseV4(RESPONSE_V4* response_v4, const int responseSize, BYTE* const rawResponse, const BYTE* const rawRequest)
  3365. {
  3366. int copySize =
  3367. V4_PRE_EPID_SIZE +
  3368. (LE32(((RESPONSE_V4*)rawResponse)->ResponseBase.PIDSize) <= PID_BUFFER_SIZE << 1 ?
  3369. LE32(((RESPONSE_V4*)rawResponse)->ResponseBase.PIDSize) :
  3370. PID_BUFFER_SIZE << 1);
  3371. int messageSize = copySize + V4_POST_EPID_SIZE;
  3372. memcpy(response_v4, rawResponse, copySize);
  3373. memcpy(&response_v4->ResponseBase.CMID, rawResponse + copySize, responseSize - copySize);
  3374. // ensure PID is null terminated
  3375. response_v4->ResponseBase.KmsPID[PID_BUFFER_SIZE-1] = 0;
  3376. uint8_t* mac = rawResponse + messageSize;
  3377. AesCmacV4(rawResponse, messageSize, mac);
  3378. REQUEST_V4* request_v4 = (REQUEST_V4*)rawRequest;
  3379. RESPONSE_RESULT result;
  3380. result.mask = (DWORD)~0;
  3381. result.PidLengthOK = checkPidLength((RESPONSE*)rawResponse);
  3382. result.VersionOK = response_v4->ResponseBase.Version == request_v4->RequestBase.Version;
  3383. result.HashOK = !memcmp(&response_v4->MAC, mac, sizeof(response_v4->MAC));
  3384. result.TimeStampOK = !memcmp(&response_v4->ResponseBase.ClientTime, &request_v4->RequestBase.ClientTime, sizeof(FILETIME));
  3385. result.ClientMachineIDOK = !memcmp(&response_v4->ResponseBase.CMID, &request_v4->RequestBase.CMID, sizeof(GUID));
  3386. result.effectiveResponseSize = responseSize;
  3387. result.correctResponseSize = sizeof(RESPONSE_V4) - sizeof(response_v4->ResponseBase.KmsPID) + LE32(response_v4->ResponseBase.PIDSize);
  3388. return result;
  3389. }
  3390. static RESPONSE_RESULT VerifyResponseV6(RESPONSE_RESULT result, const AesCtx* Ctx, RESPONSE_V6* response_v6, REQUEST_V6* request_v6, BYTE* const rawResponse)
  3391. {
  3392. // Check IVs
  3393. result.IVsOK = !memcmp // In V6 the XoredIV is actually the request IV
  3394. (
  3395. response_v6->XoredIVs,
  3396. request_v6->IV,
  3397. sizeof(response_v6->XoredIVs)
  3398. );
  3399. result.IVnotSuspicious = !!memcmp // If IVs are identical, it is obviously an emulator
  3400. (
  3401. request_v6->IV,
  3402. response_v6->IV,
  3403. sizeof(request_v6->IV)
  3404. );
  3405. // Check Hmac
  3406. int_fast8_t tolerance;
  3407. BYTE OldHmac[sizeof(response_v6->HMAC)];
  3408. result.HmacSha256OK = FALSE;
  3409. memcpy // Save received HMAC to compare with calculated HMAC later
  3410. (
  3411. OldHmac,
  3412. response_v6->HMAC,
  3413. sizeof(response_v6->HMAC)
  3414. );
  3415. //AesEncryptBlock(Ctx, Response_v6->IV); // CreateV6Hmac needs original IV as received over the network
  3416. for (tolerance = -1; tolerance < 2; tolerance++)
  3417. {
  3418. CreateV6Hmac
  3419. (
  3420. rawResponse + sizeof(response_v6->Version), // Pointer to start of the encrypted part of the response
  3421. (size_t)result.correctResponseSize - V6_UNENCRYPTED_SIZE, // size of the encrypted part
  3422. tolerance // tolerance -1, 0, or +1
  3423. );
  3424. if
  3425. ((
  3426. result.HmacSha256OK = !memcmp // Compare both HMACs
  3427. (
  3428. OldHmac,
  3429. rawResponse + (size_t)result.correctResponseSize - sizeof(response_v6->HMAC),
  3430. sizeof(OldHmac)
  3431. )
  3432. ))
  3433. {
  3434. break;
  3435. }
  3436. }
  3437. return result;
  3438. }
  3439. static RESPONSE_RESULT VerifyResponseV5(RESPONSE_RESULT result, REQUEST_V5* request_v5, RESPONSE_V5* response_v5)
  3440. {
  3441. // Check IVs: in V5 (and only v5) request and response IVs must match
  3442. result.IVsOK = !memcmp(request_v5->IV, response_v5->IV, sizeof(request_v5->IV));
  3443. // V5 has no Hmac, always set to TRUE
  3444. result.HmacSha256OK = TRUE;
  3445. return result;
  3446. }
  3447. /*
  3448. * Decrypts a KMS v5 or v6 response received from a server.
  3449. * hwid must supply a valid 16 byte buffer for v6. hwid is ignored in v5
  3450. */
  3451. RESPONSE_RESULT DecryptResponseV6(RESPONSE_V6* response_v6, int responseSize, BYTE* const response, const BYTE* const rawRequest, BYTE* hwid)
  3452. {
  3453. RESPONSE_RESULT result;
  3454. result.mask = ~0; // Set all bits in the results mask to 1. Assume success first.
  3455. result.effectiveResponseSize = responseSize;
  3456. int copySize1 =
  3457. sizeof(response_v6->Version);
  3458. // Decrypt KMS Server Response (encrypted part starts after RequestIV)
  3459. responseSize -= copySize1;
  3460. AesCtx Ctx;
  3461. int_fast8_t v6 = LE16(((RESPONSE_V6*)response)->MajorVer) > 5;
  3462. AesInitKey(&Ctx, v6 ? AesKeyV6 : AesKeyV5, v6, AES_KEY_BYTES);
  3463. AesDecryptCbc(&Ctx, NULL, response + copySize1, responseSize);
  3464. // Check padding
  3465. BYTE* lastPadByte = response + (size_t)result.effectiveResponseSize - 1;
  3466. // Must be from 1 to 16
  3467. if (!*lastPadByte || *lastPadByte > AES_BLOCK_BYTES)
  3468. {
  3469. result.DecryptSuccess = FALSE;
  3470. return result;
  3471. }
  3472. // Check if pad bytes are all the same
  3473. BYTE* padByte;
  3474. for (padByte = lastPadByte - *lastPadByte + 1; padByte < lastPadByte; padByte++)
  3475. if (*padByte != *lastPadByte)
  3476. {
  3477. result.DecryptSuccess = FALSE;
  3478. return result;
  3479. }
  3480. // Add size of Version, KmsPIDLen and variable size PID
  3481. DWORD pidSize = LE32(((RESPONSE_V6*) response)->ResponseBase.PIDSize);
  3482. copySize1 +=
  3483. V6_UNENCRYPTED_SIZE +
  3484. sizeof(response_v6->ResponseBase.PIDSize) +
  3485. (pidSize <= PID_BUFFER_SIZE << 1 ? pidSize : PID_BUFFER_SIZE << 1);
  3486. // Copy part 1 of response up to variable sized PID
  3487. memcpy(response_v6, response, copySize1);
  3488. // ensure PID is null terminated
  3489. response_v6->ResponseBase.KmsPID[PID_BUFFER_SIZE - 1] = 0;
  3490. // Copy part 2
  3491. size_t copySize2 = v6 ? V6_POST_EPID_SIZE : V5_POST_EPID_SIZE;
  3492. memcpy(&response_v6->ResponseBase.CMID, response + copySize1, copySize2);
  3493. // Decrypting the response is finished here. Now we check the results for validity
  3494. // A basic client doesn't need the stuff below this comment but we want to use vlmcs
  3495. // as a debug tool for KMS emulators.
  3496. REQUEST_V6* request_v6 = (REQUEST_V6*) rawRequest;
  3497. DWORD decryptSize = sizeof(request_v6->IV) + sizeof(request_v6->RequestBase) + sizeof(request_v6->Pad);
  3498. AesDecryptCbc(&Ctx, NULL, request_v6->IV, decryptSize);
  3499. // Check that all version informations are the same
  3500. result.VersionOK =
  3501. request_v6->Version == response_v6->ResponseBase.Version &&
  3502. request_v6->Version == response_v6->Version &&
  3503. request_v6->Version == request_v6->RequestBase.Version;
  3504. // Check Base Request
  3505. result.PidLengthOK = checkPidLength(&((RESPONSE_V6*) response)->ResponseBase);
  3506. result.TimeStampOK = !memcmp(&response_v6->ResponseBase.ClientTime, &request_v6->RequestBase.ClientTime, sizeof(FILETIME));
  3507. result.ClientMachineIDOK = IsEqualGUID(&response_v6->ResponseBase.CMID, &request_v6->RequestBase.CMID);
  3508. // Rebuild Random Key and Sha256 Hash
  3509. BYTE HashVerify[sizeof(response_v6->Hash)];
  3510. BYTE RandomKey[sizeof(response_v6->RandomXoredIVs)];
  3511. memcpy(RandomKey, request_v6->IV, sizeof(RandomKey));
  3512. XorBlock(response_v6->RandomXoredIVs, RandomKey);
  3513. Sha256(RandomKey, sizeof(RandomKey), HashVerify);
  3514. result.HashOK = !memcmp(response_v6->Hash, HashVerify, sizeof(HashVerify));
  3515. // size before encryption (padding not included)
  3516. result.correctResponseSize =
  3517. (v6 ? sizeof(RESPONSE_V6) : sizeof(RESPONSE_V5))
  3518. - sizeof(response_v6->ResponseBase.KmsPID)
  3519. + LE32(response_v6->ResponseBase.PIDSize);
  3520. // Version specific stuff
  3521. if (v6)
  3522. {
  3523. // Copy the HwId
  3524. memcpy(hwid, response_v6->HwId, sizeof(response_v6->HwId));
  3525. // Verify the V6 specific part of the response
  3526. result = VerifyResponseV6(result, &Ctx, response_v6, request_v6, response);
  3527. }
  3528. else // V5
  3529. {
  3530. // Verify the V5 specific part of the response
  3531. result = VerifyResponseV5(result, request_v6, (RESPONSE_V5*)response_v6);
  3532. }
  3533. // padded size after encryption
  3534. result.correctResponseSize += (~(result.correctResponseSize - sizeof(response_v6->ResponseBase.Version)) & 0xf) + 1;
  3535. return result;
  3536. }
  3537. #ifndef CONFIG
  3538. #define CONFIG "config.h"
  3539. #endif // CONFIG
  3540. #include CONFIG
  3541. #include "endian.h"
  3542. #if defined(__BYTE_ORDER) && defined(__BIG_ENDIAN) && defined(__LITTLE_ENDIAN) \
  3543. && defined(BS16) && defined(BS32) && defined(BS64)
  3544. #else // ! defined(__BYTE_ORDER)
  3545. void PUT_UAA64BE(void *p, unsigned long long v, unsigned int i)
  3546. {
  3547. unsigned char *_p = (unsigned char *)&((unsigned long long *)p)[i];
  3548. _p[ 0 ] = v >> 56;
  3549. _p[ 1 ] = v >> 48;
  3550. _p[ 2 ] = v >> 40;
  3551. _p[ 3 ] = v >> 32;
  3552. _p[ 4 ] = v >> 24;
  3553. _p[ 5 ] = v >> 16;
  3554. _p[ 6 ] = v >> 8;
  3555. _p[ 7 ] = v;
  3556. }
  3557. void PUT_UAA32BE(void *p, unsigned int v, unsigned int i)
  3558. {
  3559. unsigned char *_p = (unsigned char *)&((unsigned int *)p)[i];
  3560. _p[ 0 ] = v >> 24;
  3561. _p[ 1 ] = v >> 16;
  3562. _p[ 2 ] = v >> 8;
  3563. _p[ 3 ] = v;
  3564. }
  3565. void PUT_UAA16BE(void *p, unsigned short v, unsigned int i)
  3566. {
  3567. unsigned char *_p = (unsigned char *)&((unsigned short *)p)[i];
  3568. _p[ 0 ] = v >> 8;
  3569. _p[ 1 ] = v;
  3570. }
  3571. void PUT_UAA64LE(void *p, unsigned long long v, unsigned int i)
  3572. {
  3573. unsigned char *_p = (unsigned char *)&((unsigned long long *)p)[i];
  3574. _p[ 0 ] = v;
  3575. _p[ 1 ] = v >> 8;
  3576. _p[ 2 ] = v >> 16;
  3577. _p[ 3 ] = v >> 24;
  3578. _p[ 4 ] = v >> 32;
  3579. _p[ 5 ] = v >> 40;
  3580. _p[ 6 ] = v >> 48;
  3581. _p[ 7 ] = v >> 56;
  3582. }
  3583. void PUT_UAA32LE(void *p, unsigned int v, unsigned int i)
  3584. {
  3585. unsigned char *_p = (unsigned char *)&((unsigned int *)p)[i];
  3586. _p[ 0 ] = v;
  3587. _p[ 1 ] = v >> 8;
  3588. _p[ 2 ] = v >> 16;
  3589. _p[ 3 ] = v >> 24;
  3590. }
  3591. void PUT_UAA16LE(void *p, unsigned short v, unsigned int i)
  3592. {
  3593. unsigned char *_p = (unsigned char *)&((unsigned short *)p)[i];
  3594. _p[ 0 ] = v;
  3595. _p[ 1 ] = v >> 8;
  3596. }
  3597. unsigned long long GET_UAA64BE(void *p, unsigned int i)
  3598. {
  3599. unsigned char *_p = (unsigned char *)&((unsigned long long *)p)[i];
  3600. return
  3601. (unsigned long long)_p[ 0 ] << 56 |
  3602. (unsigned long long)_p[ 1 ] << 48 |
  3603. (unsigned long long)_p[ 2 ] << 40 |
  3604. (unsigned long long)_p[ 3 ] << 32 |
  3605. (unsigned long long)_p[ 4 ] << 24 |
  3606. (unsigned long long)_p[ 5 ] << 16 |
  3607. (unsigned long long)_p[ 6 ] << 8 |
  3608. (unsigned long long)_p[ 7 ];
  3609. }
  3610. unsigned int GET_UAA32BE(void *p, unsigned int i)
  3611. {
  3612. unsigned char *_p = (unsigned char *)&((unsigned int *)p)[i];
  3613. return
  3614. (unsigned int)_p[ 0 ] << 24 |
  3615. (unsigned int)_p[ 1 ] << 16 |
  3616. (unsigned int)_p[ 2 ] << 8 |
  3617. (unsigned int)_p[ 3 ];
  3618. }
  3619. unsigned short GET_UAA16BE(void *p, unsigned int i)
  3620. {
  3621. unsigned char *_p = (unsigned char *)&((unsigned short *)p)[i];
  3622. return
  3623. (unsigned short)_p[ 0 ] << 8 |
  3624. (unsigned short)_p[ 1 ];
  3625. }
  3626. unsigned long long GET_UAA64LE(void *p, unsigned int i)
  3627. {
  3628. unsigned char *_p = (unsigned char *)&((unsigned long long *)p)[i];
  3629. return
  3630. (unsigned long long)_p[ 0 ] |
  3631. (unsigned long long)_p[ 1 ] << 8 |
  3632. (unsigned long long)_p[ 2 ] << 16 |
  3633. (unsigned long long)_p[ 3 ] << 24 |
  3634. (unsigned long long)_p[ 4 ] << 32 |
  3635. (unsigned long long)_p[ 5 ] << 40 |
  3636. (unsigned long long)_p[ 6 ] << 48 |
  3637. (unsigned long long)_p[ 7 ] << 56;
  3638. }
  3639. unsigned int GET_UAA32LE(void *p, unsigned int i)
  3640. {
  3641. unsigned char *_p = (unsigned char *)&((unsigned int *)p)[i];
  3642. return
  3643. (unsigned int)_p[ 0 ] |
  3644. (unsigned int)_p[ 1 ] << 8 |
  3645. (unsigned int)_p[ 2 ] << 16 |
  3646. (unsigned int)_p[ 3 ] << 24;
  3647. }
  3648. unsigned short GET_UAA16LE(void *p, unsigned int i)
  3649. {
  3650. unsigned char *_p = (unsigned char *)&((unsigned short *)p)[i];
  3651. return
  3652. (unsigned short)_p[ 0 ] |
  3653. (unsigned short)_p[ 1 ] << 8;
  3654. }
  3655. unsigned short BE16(unsigned short x)
  3656. {
  3657. return GET_UAA16BE(&x, 0);
  3658. }
  3659. unsigned short LE16(unsigned short x)
  3660. {
  3661. return GET_UAA16LE(&x, 0);
  3662. }
  3663. unsigned int BE32(unsigned int x)
  3664. {
  3665. return GET_UAA32BE(&x, 0);
  3666. }
  3667. unsigned int LE32(unsigned int x)
  3668. {
  3669. return GET_UAA32LE(&x, 0);
  3670. }
  3671. unsigned long long BE64(unsigned long long x)
  3672. {
  3673. return GET_UAA64BE(&x, 0);
  3674. }
  3675. inline unsigned long long LE64(unsigned long long x)
  3676. {
  3677. return GET_UAA64LE(&x, 0);
  3678. }
  3679. #endif // defined(__BYTE_ORDER)
  3680. #ifndef _DEFAULT_SOURCE
  3681. #define _DEFAULT_SOURCE
  3682. #endif // _DEFAULT_SOURCE
  3683. #ifndef CONFIG
  3684. #define CONFIG "config.h"
  3685. #endif // CONFIG
  3686. #include CONFIG
  3687. #include "output.h"
  3688. #include "shared_globals.h"
  3689. #include "endian.h"
  3690. #include "helpers.h"
  3691. #ifndef NO_LOG
  3692. static void vlogger(const char *message, va_list args)
  3693. {
  3694. FILE *log;
  3695. #ifdef _NTSERVICE
  3696. if (!IsNTService && logstdout) log = stdout;
  3697. #else
  3698. if (logstdout) log = stdout;
  3699. #endif
  3700. else
  3701. {
  3702. if (fn_log == NULL) return;
  3703. #ifndef _WIN32
  3704. if (!strcmp(fn_log, "syslog"))
  3705. {
  3706. openlog("vlmcsd", LOG_CONS | LOG_PID, LOG_USER);
  3707. ////PORTABILITY: vsyslog is not in Posix but virtually all Unixes have it
  3708. vsyslog(LOG_INFO, message, args);
  3709. closelog();
  3710. return;
  3711. }
  3712. #endif // _WIN32
  3713. log = fopen(fn_log, "a");
  3714. if ( !log ) return;
  3715. }
  3716. time_t now = time(0);
  3717. #ifdef USE_THREADS
  3718. char mbstr[2048];
  3719. #else
  3720. char mbstr[24];
  3721. #endif
  3722. strftime(mbstr, sizeof(mbstr), "%Y-%m-%d %X", localtime(&now));
  3723. #ifndef USE_THREADS
  3724. fprintf(log, "%s: ", mbstr);
  3725. vfprintf(log, message, args);
  3726. fflush(log);
  3727. #else // USE_THREADS
  3728. // We write everything to a string before we really log inside the critical section
  3729. // so formatting the output can be concurrent
  3730. strcat(mbstr, ": ");
  3731. int len = strlen(mbstr);
  3732. vsnprintf(mbstr + len, sizeof(mbstr) - len, message, args);
  3733. lock_mutex(&logmutex);
  3734. fputs(mbstr, log);
  3735. fflush(log);
  3736. unlock_mutex(&logmutex);
  3737. #endif // USE_THREADS
  3738. if (log != stdout) fclose(log);
  3739. }
  3740. // Always sends to log output
  3741. int logger(const char *const fmt, ...)
  3742. {
  3743. va_list args;
  3744. va_start(args, fmt);
  3745. vlogger(fmt, args);
  3746. va_end(args);
  3747. return 0;
  3748. }
  3749. #endif //NO_LOG
  3750. // Output to stderr if it is available or to log otherwise (e.g. if running as daemon/service)
  3751. void printerrorf(const char *const fmt, ...)
  3752. {
  3753. va_list arglist;
  3754. va_start(arglist, fmt);
  3755. #ifndef NO_LOG
  3756. #ifdef _NTSERVICE
  3757. if (InetdMode || IsNTService)
  3758. #else // !_NTSERVICE
  3759. if (InetdMode)
  3760. #endif // NTSERVIICE
  3761. vlogger(fmt, arglist);
  3762. else
  3763. #endif //NO_LOG
  3764. {
  3765. vfprintf(stderr, fmt, arglist);
  3766. fflush(stderr);
  3767. }
  3768. va_end(arglist);
  3769. }
  3770. // Always output to stderr
  3771. int errorout(const char* fmt, ...)
  3772. {
  3773. va_list args;
  3774. va_start(args, fmt);
  3775. int i = vfprintf(stderr, fmt, args);
  3776. va_end(args);
  3777. fflush(stderr);
  3778. return i;
  3779. }
  3780. static const char *LicenseStatusText[] =
  3781. {
  3782. "Unlicensed", "Licensed", "OOB grace", "OOT grace", "Non-Genuine", "Notification", "Extended grace"
  3783. };
  3784. void uuid2StringLE(const GUID *const guid, char *const string)
  3785. {
  3786. sprintf(string,
  3787. #ifdef _WIN32
  3788. "%08x-%04x-%04x-%04x-%012I64x",
  3789. #else
  3790. "%08x-%04x-%04x-%04x-%012llx",
  3791. #endif
  3792. (unsigned int)LE32( guid->Data1 ),
  3793. (unsigned int)LE16( guid->Data2 ),
  3794. (unsigned int)LE16( guid->Data3 ),
  3795. (unsigned int)BE16( *(uint16_t*)guid->Data4 ),
  3796. (unsigned long long)BE64(*(uint64_t*)(guid->Data4)) & 0xffffffffffffLL
  3797. );
  3798. }
  3799. void logRequestVerbose(const REQUEST *const Request, const PRINTFUNC p)
  3800. {
  3801. char guidBuffer[GUID_STRING_LENGTH + 1];
  3802. char WorkstationBuffer[3 * WORKSTATION_NAME_BUFFER];
  3803. const char *productName;
  3804. ProdListIndex_t index;
  3805. p("Protocol version : %u.%u\n", LE16(Request->MajorVer), LE16(Request->MinorVer));
  3806. p("Client is a virtual machine : %s\n", LE32(Request->VMInfo) ? "Yes" : "No");
  3807. p("Licensing status : %u (%s)\n", (uint32_t)LE32(Request->LicenseStatus), LE32(Request->LicenseStatus) < _countof(LicenseStatusText) ? LicenseStatusText[LE32(Request->LicenseStatus)] : "Unknown");
  3808. p("Remaining time (0 = forever) : %i minutes\n", (uint32_t)LE32(Request->BindingExpiration));
  3809. uuid2StringLE(&Request->AppID, guidBuffer);
  3810. productName = getProductNameLE(&Request->AppID, AppList, &index);
  3811. p("Application ID : %s (%s)\n", guidBuffer, productName);
  3812. uuid2StringLE(&Request->ActID, guidBuffer);
  3813. #ifndef NO_EXTENDED_PRODUCT_LIST
  3814. productName = getProductNameLE(&Request->ActID, ExtendedProductList, &index);
  3815. #else
  3816. productName = "Unknown";
  3817. #endif
  3818. p("Activation ID (Product) : %s (%s)\n", guidBuffer, productName);
  3819. uuid2StringLE(&Request->KMSID, guidBuffer);
  3820. #ifndef NO_BASIC_PRODUCT_LIST
  3821. productName = getProductNameLE(&Request->KMSID, ProductList, &index);
  3822. #else
  3823. productName = "Unknown";
  3824. #endif
  3825. p("Key Management Service ID : %s (%s)\n", guidBuffer, productName);
  3826. uuid2StringLE(&Request->CMID, guidBuffer);
  3827. p("Client machine ID : %s\n", guidBuffer);
  3828. uuid2StringLE(&Request->CMID_prev, guidBuffer);
  3829. p("Previous client machine ID : %s\n", guidBuffer);
  3830. char mbstr[64];
  3831. time_t st;
  3832. st = fileTimeToUnixTime(&Request->ClientTime);
  3833. strftime(mbstr, sizeof(mbstr), "%Y-%m-%d %X", gmtime(&st));
  3834. p("Client request timestamp (UTC) : %s\n", mbstr);
  3835. ucs2_to_utf8(Request->WorkstationName, WorkstationBuffer, WORKSTATION_NAME_BUFFER, sizeof(WorkstationBuffer));
  3836. p("Workstation name : %s\n", WorkstationBuffer);
  3837. p("N count policy (minimum clients): %u\n", (uint32_t)LE32(Request->N_Policy));
  3838. }
  3839. void logResponseVerbose(const char *const ePID, const BYTE *const hwid, const RESPONSE *const response, const PRINTFUNC p)
  3840. {
  3841. char guidBuffer[GUID_STRING_LENGTH + 1];
  3842. //SYSTEMTIME st;
  3843. p("Protocol version : %u.%u\n", (uint32_t)LE16(response->MajorVer), (uint32_t)LE16(response->MinorVer));
  3844. p("KMS host extended PID : %s\n", ePID);
  3845. if (LE16(response->MajorVer) > 5)
  3846. # ifndef _WIN32
  3847. p("KMS host Hardware ID : %016llX\n", (unsigned long long)BE64(*(uint64_t*)hwid));
  3848. # else // _WIN32
  3849. p("KMS host Hardware ID : %016I64X\n", (unsigned long long)BE64(*(uint64_t*)hwid));
  3850. # endif // WIN32
  3851. uuid2StringLE(&response->CMID, guidBuffer);
  3852. p("Client machine ID : %s\n", guidBuffer);
  3853. char mbstr[64];
  3854. time_t st;
  3855. st = fileTimeToUnixTime(&response->ClientTime);
  3856. strftime(mbstr, sizeof(mbstr), "%Y-%m-%d %X", gmtime(&st));
  3857. p("Client request timestamp (UTC) : %s\n", mbstr);
  3858. p("KMS host current active clients : %u\n", (uint32_t)LE32(response->Count));
  3859. p("Renewal interval policy : %u\n", (uint32_t)LE32(response->VLRenewalInterval));
  3860. p("Activation interval policy : %u\n", (uint32_t)LE32(response->VLActivationInterval));
  3861. }
  3862. #ifndef CONFIG
  3863. #define CONFIG "config.h"
  3864. #endif // CONFIG
  3865. #include CONFIG
  3866. #include "shared_globals.h"
  3867. int global_argc, multi_argc = 0;
  3868. CARGV global_argv, multi_argv = NULL;
  3869. const char *const Version = VERSION;
  3870. DWORD VLActivationInterval = 60 * 2; // 2 hours
  3871. DWORD VLRenewalInterval = 60 * 24 * 7; // 7 days
  3872. int_fast8_t DisconnectImmediately = FALSE;
  3873. const char *const cIPv4 = "IPv4";
  3874. const char *const cIPv6 = "IPv6";
  3875. #ifndef USE_MSRPC
  3876. int_fast8_t UseMultiplexedRpc = TRUE;
  3877. int_fast8_t UseRpcNDR64 = TRUE;
  3878. int_fast8_t UseRpcBTFN = TRUE;
  3879. #endif // USE_MSRPC
  3880. #ifndef NO_SOCKETS
  3881. const char *defaultport = "1688";
  3882. #endif // NO_SOCKETS
  3883. KmsResponseParam_t KmsResponseParameters[MAX_KMSAPPS];
  3884. #if !defined(NO_SOCKETS) && !defined(NO_SIGHUP) && !defined(_WIN32)
  3885. int_fast8_t IsRestarted = FALSE;
  3886. #endif // !defined(NO_SOCKETS) && !defined(NO_SIGHUP) && !defined(_WIN32)
  3887. #if !defined(NO_TIMEOUT) && !__minix__
  3888. DWORD ServerTimeout = 30;
  3889. #endif // !defined(NO_TIMEOUT) && !__minix__
  3890. #if !defined(NO_LIMIT) && !defined (NO_SOCKETS) && !__minix__
  3891. #ifdef USE_MSRPC
  3892. uint32_t MaxTasks = RPC_C_LISTEN_MAX_CALLS_DEFAULT;
  3893. #else // !USE_MSRPC
  3894. uint32_t MaxTasks = SEM_VALUE_MAX;
  3895. #endif // !USE_MSRPC
  3896. #endif // !defined(NO_LIMIT) && !defined (NO_SOCKETS) && !__minix__
  3897. #ifndef NO_LOG
  3898. char *fn_log = NULL;
  3899. int_fast8_t logstdout = 0;
  3900. #ifndef NO_VERBOSE_LOG
  3901. int_fast8_t logverbose = 0;
  3902. #endif // NO_VERBOSE_LOG
  3903. #endif // NO_LOG
  3904. #ifndef NO_SOCKETS
  3905. int_fast8_t nodaemon = 0;
  3906. int_fast8_t InetdMode = 0;
  3907. #else
  3908. int_fast8_t nodaemon = 1;
  3909. int_fast8_t InetdMode = 1;
  3910. #endif
  3911. #ifndef NO_RANDOM_EPID
  3912. int_fast8_t RandomizationLevel = 1;
  3913. uint16_t Lcid = 0;
  3914. #endif
  3915. #ifndef NO_SOCKETS
  3916. SOCKET *SocketList;
  3917. int numsockets = 0;
  3918. #if !defined(NO_LIMIT) && !__minix__
  3919. #ifndef _WIN32 // Posix
  3920. sem_t *Semaphore;
  3921. #else // _WIN32
  3922. HANDLE Semaphore;
  3923. #endif // _WIN32
  3924. #endif // !defined(NO_LIMIT) && !__minix__
  3925. #endif // NO_SOCKETS
  3926. #ifdef _NTSERVICE
  3927. int_fast8_t IsNTService = TRUE;
  3928. int_fast8_t ServiceShutdown = FALSE;
  3929. #endif // _NTSERVICE
  3930. #ifndef NO_LOG
  3931. #ifdef USE_THREADS
  3932. #if !defined(_WIN32) && !defined(__CYGWIN__)
  3933. pthread_mutex_t logmutex = PTHREAD_MUTEX_INITIALIZER;
  3934. #else
  3935. CRITICAL_SECTION logmutex;
  3936. #endif // !defined(_WIN32) && !defined(__CYGWIN__)
  3937. #endif // USE_THREADS
  3938. #endif // NO_LOG
  3939. /*
  3940. * Helper functions used by other modules
  3941. */
  3942. #ifndef CONFIG
  3943. #define CONFIG "config.h"
  3944. #endif // CONFIG
  3945. #include CONFIG
  3946. #ifndef _WIN32
  3947. #include <errno.h>
  3948. #endif // _WIN32
  3949. #include <getopt.h>
  3950. #include <string.h>
  3951. #include <stdlib.h>
  3952. #include <ctype.h>
  3953. #include "helpers.h"
  3954. #include "output.h"
  3955. #include "endian.h"
  3956. #include "shared_globals.h"
  3957. /*
  3958. * UCS2 <-> UTF-8 functions
  3959. * All functions use little endian UCS2 since we only need it to communicate with Windows via RPC
  3960. */
  3961. // Convert one character from UTF-8 to UCS2
  3962. // Returns 0xffff, if utf-8 evaluates to > 0xfffe (outside basic multilingual pane)
  3963. WCHAR utf8_to_ucs2_char (const unsigned char *input, const unsigned char **end_ptr)
  3964. {
  3965. *end_ptr = input;
  3966. if (input[0] == 0)
  3967. return ~0;
  3968. if (input[0] < 0x80) {
  3969. *end_ptr = input + 1;
  3970. return LE16(input[0]);
  3971. }
  3972. if ((input[0] & 0xE0) == 0xE0) {
  3973. if (input[1] == 0 || input[2] == 0)
  3974. return ~0;
  3975. *end_ptr = input + 3;
  3976. return
  3977. LE16((input[0] & 0x0F)<<12 |
  3978. (input[1] & 0x3F)<<6 |
  3979. (input[2] & 0x3F));
  3980. }
  3981. if ((input[0] & 0xC0) == 0xC0) {
  3982. if (input[1] == 0)
  3983. return ~0;
  3984. *end_ptr = input + 2;
  3985. return
  3986. LE16((input[0] & 0x1F)<<6 |
  3987. (input[1] & 0x3F));
  3988. }
  3989. return ~0;
  3990. }
  3991. // Convert one character from UCS2 to UTF-8
  3992. // Returns length of UTF-8 char (1, 2 or 3) or -1 on error (UTF-16 outside UCS2)
  3993. // char *utf8 must be large enough to hold 3 bytes
  3994. int ucs2_to_utf8_char (const WCHAR ucs2_le, char *utf8)
  3995. {
  3996. const WCHAR ucs2 = LE16(ucs2_le);
  3997. if (ucs2 < 0x80) {
  3998. utf8[0] = ucs2;
  3999. utf8[1] = '\0';
  4000. return 1;
  4001. }
  4002. if (ucs2 >= 0x80 && ucs2 < 0x800) {
  4003. utf8[0] = (ucs2 >> 6) | 0xC0;
  4004. utf8[1] = (ucs2 & 0x3F) | 0x80;
  4005. utf8[2] = '\0';
  4006. return 2;
  4007. }
  4008. if (ucs2 >= 0x800 && ucs2 < 0xFFFF) {
  4009. if (ucs2 >= 0xD800 && ucs2 <= 0xDFFF) {
  4010. /* Ill-formed (UTF-16 ouside of BMP) */
  4011. return -1;
  4012. }
  4013. utf8[0] = ((ucs2 >> 12) ) | 0xE0;
  4014. utf8[1] = ((ucs2 >> 6 ) & 0x3F) | 0x80;
  4015. utf8[2] = ((ucs2 ) & 0x3F) | 0x80;
  4016. utf8[3] = '\0';
  4017. return 3;
  4018. }
  4019. return -1;
  4020. }
  4021. // Converts UTF8 to UCS2. Returns size in bytes of the converted string or -1 on error
  4022. size_t utf8_to_ucs2(WCHAR* const ucs2_le, const char* const utf8, const size_t maxucs2, const size_t maxutf8)
  4023. {
  4024. const unsigned char* current_utf8 = (unsigned char*)utf8;
  4025. WCHAR* current_ucs2_le = ucs2_le;
  4026. for (; *current_utf8; current_ucs2_le++)
  4027. {
  4028. size_t size = (char*)current_utf8 - utf8;
  4029. if (size >= maxutf8) return (size_t)-1;
  4030. if (((*current_utf8 & 0xc0) == 0xc0) && (size >= maxutf8 - 1)) return (size_t)-1;
  4031. if (((*current_utf8 & 0xe0) == 0xe0) && (size >= maxutf8 - 2)) return (size_t)-1;
  4032. if (current_ucs2_le - ucs2_le >= (intptr_t)maxucs2 - 1) return (size_t)-1;
  4033. *current_ucs2_le = utf8_to_ucs2_char(current_utf8, &current_utf8);
  4034. current_ucs2_le[1] = 0;
  4035. if (*current_ucs2_le == (WCHAR)-1) return (size_t)-1;
  4036. }
  4037. return current_ucs2_le - ucs2_le;
  4038. }
  4039. // Converts UCS2 to UTF-8. Return TRUE or FALSE
  4040. BOOL ucs2_to_utf8(const WCHAR* const ucs2_le, char* utf8, size_t maxucs2, size_t maxutf8)
  4041. {
  4042. char utf8_char[4];
  4043. const WCHAR* current_ucs2 = ucs2_le;
  4044. unsigned int index_utf8 = 0;
  4045. for(*utf8 = 0; *current_ucs2; current_ucs2++)
  4046. {
  4047. if (current_ucs2 - ucs2_le > (intptr_t)maxucs2) return FALSE;
  4048. int len = ucs2_to_utf8_char(*current_ucs2, utf8_char);
  4049. if (index_utf8 + len > maxutf8) return FALSE;
  4050. strncat(utf8, utf8_char, len);
  4051. index_utf8+=len;
  4052. }
  4053. return TRUE;
  4054. }
  4055. /* End of UTF-8 <-> UCS2 conversion */
  4056. // Checks, whether a string is a valid integer number between min and max. Returns TRUE or FALSE. Puts int value in *value
  4057. BOOL stringToInt(const char *const szValue, const unsigned int min, const unsigned int max, unsigned int *const value)
  4058. {
  4059. char *nextchar;
  4060. errno = 0;
  4061. long long result = strtoll(szValue, &nextchar, 10);
  4062. if (errno || result < (long long)min || result > (long long)max || *nextchar)
  4063. {
  4064. return FALSE;
  4065. }
  4066. *value = (unsigned int)result;
  4067. return TRUE;
  4068. }
  4069. //Converts a String Guid to a host binary guid in host endianess
  4070. int_fast8_t string2Uuid(const char *const restrict input, GUID *const restrict guid)
  4071. {
  4072. int i;
  4073. if (strlen(input) < GUID_STRING_LENGTH) return FALSE;
  4074. if (input[8] != '-' || input[13] != '-' || input[18] != '-' || input[23] != '-') return FALSE;
  4075. for (i = 0; i < GUID_STRING_LENGTH; i++)
  4076. {
  4077. if (i == 8 || i == 13 || i == 18 || i == 23) continue;
  4078. const char c = toupper((int)input[i]);
  4079. if (c < '0' || c > 'F' || (c > '9' && c < 'A')) return FALSE;
  4080. }
  4081. char inputCopy[GUID_STRING_LENGTH + 1];
  4082. strncpy(inputCopy, input, GUID_STRING_LENGTH + 1);
  4083. inputCopy[8] = inputCopy[13] = inputCopy[18] = 0;
  4084. hex2bin((BYTE*)&guid->Data1, inputCopy, 8);
  4085. hex2bin((BYTE*)&guid->Data2, inputCopy + 9, 4);
  4086. hex2bin((BYTE*)&guid->Data3, inputCopy + 14, 4);
  4087. hex2bin(guid->Data4, input + 19, 16);
  4088. guid->Data1 = BE32(guid->Data1);
  4089. guid->Data2 = BE16(guid->Data2);
  4090. guid->Data3 = BE16(guid->Data3);
  4091. return TRUE;
  4092. }
  4093. // convert GUID to little-endian
  4094. void LEGUID(GUID *const restrict out, const GUID* const restrict in)
  4095. {
  4096. #if __BYTE_ORDER != __LITTLE_ENDIAN
  4097. out->Data1 = LE32(in->Data1);
  4098. out->Data2 = LE16(in->Data2);
  4099. out->Data3 = LE16(in->Data3);
  4100. memcpy(out->Data4, in->Data4, sizeof(out->Data4));
  4101. #else
  4102. memcpy(out, in, sizeof(GUID));
  4103. #endif
  4104. }
  4105. //Checks a command line argument if it is numeric and between min and max. Returns the numeric value or exits on error
  4106. __pure unsigned int getOptionArgumentInt(const char o, const unsigned int min, const unsigned int max)
  4107. {
  4108. unsigned int result;
  4109. if (!stringToInt(optarg, min, max, &result))
  4110. {
  4111. printerrorf("Fatal: Option \"-%c\" must be numeric between %u and %u.\n", o, min, max);
  4112. exit(!0);
  4113. }
  4114. return result;
  4115. }
  4116. // Resets getopt() to start parsing from the beginning
  4117. void optReset(void)
  4118. {
  4119. #if __minix__ || defined(__BSD__) || defined(__APPLE__) || defined(__FreeBSD__) || defined(__NetBSD__) || defined(__DragonFly__) || defined(__OpenBSD__)
  4120. optind = 1;
  4121. optreset = 1; // Makes newer BSD getopt happy
  4122. #elif defined(__UCLIBC__) // uClibc headers also define __GLIBC__ so be careful here
  4123. optind = 0; // uClibc seeks compatibility with GLIBC
  4124. #elif defined(__GLIBC__)
  4125. optind = 0; // Makes GLIBC getopt happy
  4126. #else // Standard for most systems
  4127. optind = 1;
  4128. #endif
  4129. }
  4130. #if defined(_WIN32) || defined(USE_MSRPC)
  4131. // Returns a static message buffer containing text for a given Win32 error. Not thread safe (same as strerror)
  4132. char* win_strerror(const int message)
  4133. {
  4134. #define STRERROR_BUFFER_SIZE 256
  4135. static char buffer[STRERROR_BUFFER_SIZE];
  4136. FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS | FORMAT_MESSAGE_MAX_WIDTH_MASK, NULL, message, 0, buffer, STRERROR_BUFFER_SIZE, NULL);
  4137. return buffer;
  4138. }
  4139. #endif // defined(_WIN32) || defined(USE_MSRPC)
  4140. /*
  4141. * parses an address in the form host:[port] in addr
  4142. * returns host and port in seperate strings
  4143. */
  4144. void parseAddress(char *const addr, char** szHost, char** szPort)
  4145. {
  4146. *szHost = addr;
  4147. # ifndef NO_SOCKETS
  4148. *szPort = (char*)defaultport;
  4149. # else // NO_SOCKETS
  4150. *szPort = "1688";
  4151. # endif // NO_SOCKETS
  4152. char *lastcolon = strrchr(addr, ':');
  4153. char *firstcolon = strchr(addr, ':');
  4154. char *closingbracket = strrchr(addr, ']');
  4155. if (*addr == '[' && closingbracket) //Address in brackets
  4156. {
  4157. *closingbracket = 0;
  4158. (*szHost)++;
  4159. if (closingbracket[1] == ':')
  4160. *szPort = closingbracket + 2;
  4161. }
  4162. else if (firstcolon && firstcolon == lastcolon) //IPv4 address or hostname with port
  4163. {
  4164. *firstcolon = 0;
  4165. *szPort = firstcolon + 1;
  4166. }
  4167. }
  4168. // Initialize random generator (needs to be done in each thread)
  4169. void randomNumberInit()
  4170. {
  4171. struct timeval tv;
  4172. gettimeofday(&tv, NULL);
  4173. srand((unsigned int)(tv.tv_sec ^ tv.tv_usec));
  4174. }
  4175. // We always exit immediately if any OOM condition occurs
  4176. __noreturn void OutOfMemory(void)
  4177. {
  4178. errorout("Fatal: Out of memory");
  4179. exit(!0);
  4180. }
  4181. void* vlmcsd_malloc(size_t len)
  4182. {
  4183. void* buf = malloc(len);
  4184. if (!buf) OutOfMemory();
  4185. return buf;
  4186. }
  4187. /*
  4188. * Converts hex digits to bytes in big-endian order.
  4189. * Ignores any non-hex characters
  4190. */
  4191. void hex2bin(BYTE *const bin, const char *hex, const size_t maxbin)
  4192. {
  4193. static const char *const hexdigits = "0123456789ABCDEF";
  4194. char* nextchar;
  4195. size_t i;
  4196. for (i = 0; (i < 16) && utf8_to_ucs2_char((const unsigned char*)hex, (const unsigned char**)&nextchar) != (WCHAR)-1; hex = nextchar)
  4197. {
  4198. const char* pos = strchr(hexdigits, toupper((int)*hex));
  4199. if (!pos) continue;
  4200. if (!(i & 1)) bin[i >> 1] = 0;
  4201. bin[i >> 1] |= (char)(pos - hexdigits);
  4202. if (!(i & 1)) bin[i >> 1] <<= 4;
  4203. i++;
  4204. if (i >> 1 > maxbin) break;
  4205. }
  4206. }
  4207. __pure BOOL getArgumentBool(int_fast8_t *result, const char *const argument)
  4208. {
  4209. if (
  4210. !strncasecmp(argument, "true", 4) ||
  4211. !strncasecmp(argument, "on", 2) ||
  4212. !strncasecmp(argument, "yes", 3) ||
  4213. !strncasecmp(argument, "1", 1)
  4214. )
  4215. {
  4216. *result = TRUE;
  4217. return TRUE;
  4218. }
  4219. else if (
  4220. !strncasecmp(argument, "false", 5) ||
  4221. !strncasecmp(argument, "off", 3) ||
  4222. !strncasecmp(argument, "no", 2) ||
  4223. !strncasecmp(argument, "0", 1)
  4224. )
  4225. {
  4226. *result = FALSE;
  4227. return TRUE;
  4228. }
  4229. return FALSE;
  4230. }
  4231. #ifndef CONFIG
  4232. #define CONFIG "config.h"
  4233. #endif // CONFIG
  4234. #include CONFIG
  4235. #ifndef USE_MSRPC
  4236. #ifndef _GNU_SOURCE
  4237. #define _GNU_SOURCE
  4238. #endif
  4239. #include <string.h>
  4240. #ifndef _WIN32
  4241. #include <signal.h>
  4242. #include <unistd.h>
  4243. #include <fcntl.h>
  4244. #include <errno.h>
  4245. #include <netinet/in.h>
  4246. #endif // WIN32
  4247. #include "network.h"
  4248. #include "endian.h"
  4249. #include "output.h"
  4250. #include "helpers.h"
  4251. #include "shared_globals.h"
  4252. #include "rpc.h"
  4253. #ifndef _WIN32
  4254. typedef ssize_t (*sendrecv_t)(int, void*, size_t, int);
  4255. #else
  4256. typedef int (WINAPI *sendrecv_t)(SOCKET, void*, int, int);
  4257. #endif
  4258. // Send or receive a fixed number of bytes regardless if received in one or more chunks
  4259. int_fast8_t sendrecv(SOCKET sock, BYTE *data, int len, int_fast8_t do_send)
  4260. {
  4261. int n;
  4262. sendrecv_t f = do_send
  4263. ? (sendrecv_t) send
  4264. : (sendrecv_t) recv;
  4265. do
  4266. {
  4267. n = f(sock, data, len, 0);
  4268. }
  4269. while (
  4270. ( n < 0 && socket_errno == VLMCSD_EINTR ) || ( n > 0 && ( data += n, (len -= n) > 0 ) ));
  4271. return ! len;
  4272. }
  4273. static int_fast8_t ip2str(char *restrict result, const size_t resultLength, const struct sockaddr *const restrict socketAddress, const socklen_t socketLength)
  4274. {
  4275. static const char *const fIPv4 = "%s:%s";
  4276. static const char *const fIPv6 = "[%s]:%s";
  4277. char ipAddress[64], portNumber[8];
  4278. if (getnameinfo
  4279. (
  4280. socketAddress,
  4281. socketLength,
  4282. ipAddress,
  4283. sizeof(ipAddress),
  4284. portNumber,
  4285. sizeof(portNumber),
  4286. NI_NUMERICHOST | NI_NUMERICSERV
  4287. ))
  4288. {
  4289. return FALSE;
  4290. }
  4291. if ((unsigned int)snprintf(result, resultLength, socketAddress->sa_family == AF_INET6 ? fIPv6 : fIPv4, ipAddress, portNumber) > resultLength) return FALSE;
  4292. return TRUE;
  4293. }
  4294. static int_fast8_t getSocketList(struct addrinfo **saList, const char *const addr, const int flags, const int AddressFamily)
  4295. {
  4296. int status;
  4297. char *szHost, *szPort;
  4298. size_t len = strlen(addr) + 1;
  4299. // Don't alloca too much
  4300. if (len > 264) return FALSE;
  4301. char *addrcopy = (char*)alloca(len);
  4302. memcpy(addrcopy, addr, len);
  4303. parseAddress(addrcopy, &szHost, &szPort);
  4304. struct addrinfo hints;
  4305. memset(&hints, 0, sizeof(struct addrinfo));
  4306. hints.ai_family = AddressFamily;
  4307. hints.ai_socktype = SOCK_STREAM;
  4308. hints.ai_protocol = IPPROTO_TCP;
  4309. hints.ai_flags = flags;
  4310. if ((status = getaddrinfo(szHost, szPort, &hints, saList)))
  4311. {
  4312. printerrorf("Warning: %s: %s\n", addr, gai_strerror(status));
  4313. return FALSE;
  4314. }
  4315. return TRUE;
  4316. }
  4317. static int_fast8_t setBlockingEnabled(SOCKET fd, int_fast8_t blocking)
  4318. {
  4319. if (fd == INVALID_SOCKET) return FALSE;
  4320. #ifdef _WIN32
  4321. unsigned long mode = blocking ? 0 : 1;
  4322. return (ioctlsocket(fd, FIONBIO, &mode) == 0) ? TRUE : FALSE;
  4323. #else // POSIX
  4324. int flags = fcntl(fd, F_GETFL, 0);
  4325. if (flags < 0) return FALSE;
  4326. flags = blocking ? (flags & ~O_NONBLOCK) : (flags | O_NONBLOCK);
  4327. return (fcntl(fd, F_SETFL, flags) == 0) ? TRUE : FALSE;
  4328. #endif // POSIX
  4329. }
  4330. int_fast8_t isDisconnected(const SOCKET s)
  4331. {
  4332. char buffer[1];
  4333. if (!setBlockingEnabled(s, FALSE)) return TRUE;
  4334. int n = recv(s, buffer, 1, MSG_PEEK);
  4335. if (!setBlockingEnabled(s, TRUE)) return TRUE;
  4336. if (n == 0) return TRUE;
  4337. return FALSE;
  4338. }
  4339. // Connect to TCP address addr (e.g. "kms.example.com:1688") and return an
  4340. // open socket for the connection if successful or INVALID_SOCKET otherwise
  4341. SOCKET connectToAddress(const char *const addr, const int AddressFamily, int_fast8_t showHostName)
  4342. {
  4343. struct addrinfo *saList, *sa;
  4344. SOCKET s = INVALID_SOCKET;
  4345. char szAddr[128];
  4346. if (!getSocketList(&saList, addr, 0, AddressFamily)) return INVALID_SOCKET;
  4347. for (sa = saList; sa; sa = sa->ai_next)
  4348. {
  4349. // struct sockaddr_in* addr4 = (struct sockaddr_in*)sa->ai_addr;
  4350. // struct sockaddr_in6* addr6 = (struct sockaddr_in6*)sa->ai_addr;
  4351. if (ip2str(szAddr, sizeof(szAddr), sa->ai_addr, sa->ai_addrlen))
  4352. {
  4353. if (showHostName)
  4354. printf("Connecting to %s (%s) ... ", addr, szAddr);
  4355. else
  4356. printf("Connecting to %s ... ", szAddr);
  4357. fflush(stdout);
  4358. }
  4359. s = socket(sa->ai_family, SOCK_STREAM, IPPROTO_TCP);
  4360. # if !defined(NO_TIMEOUT) && !__minix__
  4361. # ifndef _WIN32 // Standard Posix timeout structure
  4362. struct timeval to;
  4363. to.tv_sec = 10;
  4364. to.tv_usec = 0;
  4365. # else // Windows requires a DWORD with milliseconds
  4366. DWORD to = 10000;
  4367. # endif // _WIN32
  4368. setsockopt(s, SOL_SOCKET, SO_RCVTIMEO, (sockopt_t)&to, sizeof(to));
  4369. setsockopt(s, SOL_SOCKET, SO_SNDTIMEO, (sockopt_t)&to, sizeof(to));
  4370. # endif // !defined(NO_TIMEOUT) && !__minix__
  4371. if (!connect(s, sa->ai_addr, sa->ai_addrlen))
  4372. {
  4373. printf("successful\n");
  4374. break;
  4375. }
  4376. errorout("%s\n", socket_errno == VLMCSD_EINPROGRESS ? "Timed out" : vlmcsd_strerror(socket_errno));
  4377. socketclose(s);
  4378. s = INVALID_SOCKET;
  4379. }
  4380. freeaddrinfo(saList);
  4381. return s;
  4382. }
  4383. #ifndef NO_SOCKETS
  4384. // Create a Listening socket for addrinfo sa and return socket s
  4385. // szHost and szPort are for logging only
  4386. static int listenOnAddress(const struct addrinfo *const ai, SOCKET *s)
  4387. {
  4388. int error;
  4389. char ipstr[64];
  4390. ip2str(ipstr, sizeof(ipstr), ai->ai_addr, ai->ai_addrlen);
  4391. //*s = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol);
  4392. *s = socket(ai->ai_family, SOCK_STREAM, IPPROTO_TCP);
  4393. if (*s == INVALID_SOCKET)
  4394. {
  4395. error = socket_errno;
  4396. printerrorf("Warning: %s error. %s\n", ai->ai_family == AF_INET6 ? cIPv6 : cIPv4, vlmcsd_strerror(error));
  4397. return error;
  4398. }
  4399. # if !defined(_WIN32) && !defined(NO_SIGHUP)
  4400. int flags = fcntl(*s, F_GETFD, 0);
  4401. if (flags != -1)
  4402. {
  4403. flags |= FD_CLOEXEC;
  4404. fcntl(*s, F_SETFD, flags);
  4405. }
  4406. # ifdef _PEDANTIC
  4407. else
  4408. {
  4409. printerrorf("Warning: Could not set FD_CLOEXEC flag on %s: %s\n", ipstr, vlmcsd_strerror(errno));
  4410. }
  4411. # endif // _PEDANTIC
  4412. # endif // !defined(_WIN32) && !defined(NO_SIGHUP)
  4413. BOOL socketOption = TRUE;
  4414. // fix for lame tomato toolchain
  4415. # ifndef IPV6_V6ONLY
  4416. # ifdef __linux__
  4417. # define IPV6_V6ONLY (26)
  4418. # endif // __linux__
  4419. # endif // IPV6_V6ONLY
  4420. # ifdef IPV6_V6ONLY
  4421. if (ai->ai_family == AF_INET6) setsockopt(*s, IPPROTO_IPV6, IPV6_V6ONLY, (sockopt_t)&socketOption, sizeof(socketOption));
  4422. # endif
  4423. # ifndef _WIN32
  4424. setsockopt(*s, SOL_SOCKET, SO_REUSEADDR, (sockopt_t)&socketOption, sizeof(socketOption));
  4425. # endif
  4426. if (bind(*s, ai->ai_addr, ai->ai_addrlen) || listen(*s, SOMAXCONN))
  4427. {
  4428. error = socket_errno;
  4429. printerrorf("Warning: %s: %s\n", ipstr, vlmcsd_strerror(error));
  4430. socketclose(*s);
  4431. return error;
  4432. }
  4433. # ifndef NO_LOG
  4434. logger("Listening on %s\n", ipstr);
  4435. # endif
  4436. return 0;
  4437. }
  4438. // Adds a listening socket for an address string,
  4439. // e.g. 127.0.0.1:1688 or [2001:db8:dead:beef::1]:1688
  4440. BOOL addListeningSocket(const char *const addr)
  4441. {
  4442. struct addrinfo *aiList, *ai;
  4443. int result = FALSE;
  4444. SOCKET *s = SocketList + numsockets;
  4445. if (getSocketList(&aiList, addr, AI_PASSIVE | AI_NUMERICHOST, AF_UNSPEC))
  4446. {
  4447. for (ai = aiList; ai; ai = ai->ai_next)
  4448. {
  4449. // struct sockaddr_in* addr4 = (struct sockaddr_in*)sa->ai_addr;
  4450. // struct sockaddr_in6* addr6 = (struct sockaddr_in6*)sa->ai_addr;
  4451. if (numsockets >= FD_SETSIZE)
  4452. {
  4453. #ifdef _PEDANTIC // Do not report this error in normal builds to keep file size low
  4454. printerrorf("Warning: Cannot listen on %s. Your OS only supports %u listening sockets in an FD_SET.\n", addr, FD_SETSIZE);
  4455. #endif
  4456. break;
  4457. }
  4458. if (!listenOnAddress(ai, s))
  4459. {
  4460. numsockets++;
  4461. result = TRUE;
  4462. }
  4463. }
  4464. freeaddrinfo(aiList);
  4465. }
  4466. return result;
  4467. }
  4468. // Just create some dummy sockets to see if we have a specific protocol (IPv4 or IPv6)
  4469. __pure int_fast8_t checkProtocolStack(const int addressfamily)
  4470. {
  4471. SOCKET s; // = INVALID_SOCKET;
  4472. s = socket(addressfamily, SOCK_STREAM, 0);
  4473. int_fast8_t success = (s != INVALID_SOCKET);
  4474. socketclose(s);
  4475. return success;
  4476. }
  4477. // Build an fd_set of all listening socket then use select to wait for an incoming connection
  4478. static SOCKET network_accept_any()
  4479. {
  4480. fd_set ListeningSocketsList;
  4481. SOCKET maxSocket, sock;
  4482. int i;
  4483. int status;
  4484. FD_ZERO(&ListeningSocketsList);
  4485. maxSocket = 0;
  4486. for (i = 0; i < numsockets; i++)
  4487. {
  4488. FD_SET(SocketList[i], &ListeningSocketsList);
  4489. if (SocketList[i] > maxSocket) maxSocket = SocketList[i];
  4490. }
  4491. status = select(maxSocket + 1, &ListeningSocketsList, NULL, NULL, NULL);
  4492. if (status < 0) return INVALID_SOCKET;
  4493. sock = INVALID_SOCKET;
  4494. for (i = 0; i < numsockets; i++)
  4495. {
  4496. if (FD_ISSET(SocketList[i], &ListeningSocketsList))
  4497. {
  4498. sock = SocketList[i];
  4499. break;
  4500. }
  4501. }
  4502. if (sock == INVALID_SOCKET)
  4503. return INVALID_SOCKET;
  4504. else
  4505. return accept(sock, NULL, NULL);
  4506. }
  4507. void closeAllListeningSockets()
  4508. {
  4509. int i;
  4510. for (i = 0; i < numsockets; i++)
  4511. {
  4512. shutdown(SocketList[i], VLMCSD_SHUT_RDWR);
  4513. socketclose(SocketList[i]);
  4514. }
  4515. }
  4516. #endif // NO_SOCKETS
  4517. static void serveClient(const SOCKET s_client, const DWORD RpcAssocGroup)
  4518. {
  4519. # if !defined(NO_TIMEOUT) && !__minix__
  4520. # ifndef _WIN32 // Standard Posix timeout structure
  4521. struct timeval to;
  4522. to.tv_sec = ServerTimeout;
  4523. to.tv_usec = 0;
  4524. #else // Windows requires a DWORD with milliseconds
  4525. DWORD to = ServerTimeout * 1000;
  4526. # endif // _WIN32
  4527. # if !defined(NO_LOG) && defined(_PEDANTIC)
  4528. int result =
  4529. setsockopt(s_client, SOL_SOCKET, SO_RCVTIMEO, (sockopt_t)&to, sizeof(to)) ||
  4530. setsockopt(s_client, SOL_SOCKET, SO_SNDTIMEO, (sockopt_t)&to, sizeof(to));
  4531. if (result) logger("Warning: Set timeout failed: %s\n", vlmcsd_strerror(socket_errno));
  4532. # else // !(!defined(NO_LOG) && defined(_PEDANTIC))
  4533. setsockopt(s_client, SOL_SOCKET, SO_RCVTIMEO, (sockopt_t)&to, sizeof(to));
  4534. setsockopt(s_client, SOL_SOCKET, SO_SNDTIMEO, (sockopt_t)&to, sizeof(to));
  4535. # endif // !(!defined(NO_LOG) && defined(_PEDANTIC))
  4536. # endif // !defined(NO_TIMEOUT) && !__minix__
  4537. char ipstr[64];
  4538. socklen_t len;
  4539. struct sockaddr_storage addr;
  4540. len = sizeof addr;
  4541. if (getpeername(s_client, (struct sockaddr*)&addr, &len) ||
  4542. !ip2str(ipstr, sizeof(ipstr), (struct sockaddr*)&addr, len))
  4543. {
  4544. # if !defined(NO_LOG) && defined(_PEDANTIC)
  4545. logger("Fatal: Cannot determine client's IP address: %s\n", vlmcsd_strerror(errno));
  4546. # endif // !defined(NO_LOG) && defined(_PEDANTIC)
  4547. socketclose(s_client);
  4548. return;
  4549. }
  4550. # ifndef NO_LOG
  4551. const char *const connection_type = addr.ss_family == AF_INET6 ? cIPv6 : cIPv4;
  4552. static const char *const cAccepted = "accepted";
  4553. static const char *const cClosed = "closed";
  4554. static const char *const fIP = "%s connection %s: %s.\n";
  4555. logger(fIP, connection_type, cAccepted, ipstr);
  4556. #endif // NO_LOG
  4557. rpcServer(s_client, RpcAssocGroup, ipstr);
  4558. # ifndef NO_LOG
  4559. logger(fIP, connection_type, cClosed, ipstr);
  4560. # endif // NO_LOG
  4561. socketclose(s_client);
  4562. }
  4563. #ifndef NO_SOCKETS
  4564. static void post_sem(void)
  4565. {
  4566. #if !defined(NO_LIMIT) && !__minix__
  4567. if (!InetdMode && MaxTasks != SEM_VALUE_MAX)
  4568. {
  4569. semaphore_post(Semaphore);
  4570. }
  4571. #endif // !defined(NO_LIMIT) && !__minix__
  4572. }
  4573. static void wait_sem(void)
  4574. {
  4575. #if !defined(NO_LIMIT) && !__minix__
  4576. if (!InetdMode && MaxTasks != SEM_VALUE_MAX)
  4577. {
  4578. semaphore_wait(Semaphore);
  4579. }
  4580. #endif // !defined(NO_LIMIT) && !__minix__
  4581. }
  4582. #endif // NO_SOCKETS
  4583. #if defined(USE_THREADS) && !defined(NO_SOCKETS)
  4584. #if defined(_WIN32) || defined(__CYGWIN__) // Win32 Threads
  4585. static DWORD WINAPI serveClientThreadProc(PCLDATA clData)
  4586. #else // Posix threads
  4587. static void *serveClientThreadProc (PCLDATA clData)
  4588. #endif // Thread proc is identical in WIN32 and Posix threads
  4589. {
  4590. serveClient(clData->socket, clData->RpcAssocGroup);
  4591. free(clData);
  4592. post_sem();
  4593. return 0;
  4594. }
  4595. #endif // USE_THREADS
  4596. #ifndef NO_SOCKETS
  4597. #if defined(USE_THREADS) && (defined(_WIN32) || defined(__CYGWIN__)) // Windows Threads
  4598. static int serveClientAsyncWinThreads(const PCLDATA thr_CLData)
  4599. {
  4600. wait_sem();
  4601. HANDLE h = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)serveClientThreadProc, thr_CLData, 0, NULL);
  4602. if (h)
  4603. CloseHandle(h);
  4604. else
  4605. {
  4606. socketclose(thr_CLData->socket);
  4607. free(thr_CLData);
  4608. post_sem();
  4609. return GetLastError();
  4610. }
  4611. return NO_ERROR;
  4612. }
  4613. #endif // defined(USE_THREADS) && defined(_WIN32) // Windows Threads
  4614. #if defined(USE_THREADS) && !defined(_WIN32) && !defined(__CYGWIN__) // Posix Threads
  4615. static int ServeClientAsyncPosixThreads(const PCLDATA thr_CLData)
  4616. {
  4617. pthread_t p_thr;
  4618. pthread_attr_t attr;
  4619. wait_sem();
  4620. // Must set detached state to avoid memory leak
  4621. if (pthread_attr_init(&attr) ||
  4622. pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED) ||
  4623. pthread_create(&p_thr, &attr, (void * (*)(void *))serveClientThreadProc, thr_CLData))
  4624. {
  4625. socketclose(thr_CLData->socket);
  4626. free(thr_CLData);
  4627. post_sem();
  4628. return !0;
  4629. }
  4630. return 0;
  4631. }
  4632. #endif // defined(USE_THREADS) && !defined(_WIN32) // Posix Threads
  4633. #ifndef USE_THREADS // fork() implementation
  4634. static void ChildSignalHandler(const int signal)
  4635. {
  4636. if (signal == SIGHUP) return;
  4637. post_sem();
  4638. #ifndef NO_LOG
  4639. logger("Warning: Child killed/crashed by %s\n", strsignal(signal));
  4640. #endif // NO_LOG
  4641. exit(!0);
  4642. }
  4643. static int ServeClientAsyncFork(const SOCKET s_client, const DWORD RpcAssocGroup)
  4644. {
  4645. int pid;
  4646. wait_sem();
  4647. if ((pid = fork()) < 0)
  4648. {
  4649. return errno;
  4650. }
  4651. else if ( pid )
  4652. {
  4653. // Parent process
  4654. socketclose(s_client);
  4655. return 0;
  4656. }
  4657. else
  4658. {
  4659. // Child process
  4660. // Setup a Child Handler for most common termination signals
  4661. struct sigaction sa;
  4662. sa.sa_flags = 0;
  4663. sa.sa_handler = ChildSignalHandler;
  4664. static int signallist[] = { SIGHUP, SIGINT, SIGTERM, SIGSEGV, SIGILL, SIGFPE, SIGBUS };
  4665. if (!sigemptyset(&sa.sa_mask))
  4666. {
  4667. uint_fast8_t i;
  4668. for (i = 0; i < _countof(signallist); i++)
  4669. {
  4670. sigaction(signallist[i], &sa, NULL);
  4671. }
  4672. }
  4673. serveClient(s_client, RpcAssocGroup);
  4674. post_sem();
  4675. exit(0);
  4676. }
  4677. }
  4678. #endif
  4679. int serveClientAsync(const SOCKET s_client, const DWORD RpcAssocGroup)
  4680. {
  4681. #ifndef USE_THREADS // fork() implementation
  4682. return ServeClientAsyncFork(s_client, RpcAssocGroup);
  4683. #else // threads implementation
  4684. PCLDATA thr_CLData = (PCLDATA)vlmcsd_malloc(sizeof(CLDATA));
  4685. thr_CLData->socket = s_client;
  4686. thr_CLData->RpcAssocGroup = RpcAssocGroup;
  4687. #if defined(_WIN32) || defined (__CYGWIN__) // Windows threads
  4688. return serveClientAsyncWinThreads(thr_CLData);
  4689. #else // Posix Threads
  4690. return ServeClientAsyncPosixThreads(thr_CLData);
  4691. #endif // Posix Threads
  4692. #endif // USE_THREADS
  4693. }
  4694. #endif // NO_SOCKETS
  4695. int runServer()
  4696. {
  4697. DWORD RpcAssocGroup = rand32();
  4698. // If compiled for inetd-only mode just serve the stdin socket
  4699. #ifdef NO_SOCKETS
  4700. serveClient(STDIN_FILENO, RpcAssocGroup);
  4701. return 0;
  4702. #else
  4703. // In inetd mode just handle the stdin socket
  4704. if (InetdMode)
  4705. {
  4706. serveClient(STDIN_FILENO, RpcAssocGroup);
  4707. return 0;
  4708. }
  4709. // Standalone mode
  4710. for (;;)
  4711. {
  4712. int error;
  4713. SOCKET s_client;
  4714. if ( (s_client = network_accept_any()) == INVALID_SOCKET )
  4715. {
  4716. error = socket_errno;
  4717. if (error == VLMCSD_EINTR || error == VLMCSD_ECONNABORTED) continue;
  4718. #ifdef _NTSERVICE
  4719. if (ServiceShutdown) return 0;
  4720. #endif
  4721. #ifndef NO_LOG
  4722. logger("Fatal: %s\n",vlmcsd_strerror(error));
  4723. #endif
  4724. return error;
  4725. }
  4726. RpcAssocGroup++;
  4727. serveClientAsync(s_client, RpcAssocGroup);
  4728. }
  4729. #endif // NO_SOCKETS
  4730. return 0;
  4731. }
  4732. #endif // USE_MSRPC
  4733. #ifndef _DEFAULT_SOURCE
  4734. #define _DEFAULT_SOURCE
  4735. #endif // _DEFAULT_SOURCE
  4736. #ifndef CONFIG
  4737. #define CONFIG "config.h"
  4738. #endif // CONFIG
  4739. #include CONFIG
  4740. #ifndef USE_MSRPC
  4741. #include <stdlib.h>
  4742. #include <stdio.h>
  4743. #include <string.h>
  4744. #include <stdint.h>
  4745. #include <ctype.h>
  4746. #include <time.h>
  4747. #if !defined(_WIN32)
  4748. #include <sys/socket.h>
  4749. #include <netdb.h>
  4750. #endif
  4751. #include "rpc.h"
  4752. #include "output.h"
  4753. #include "crypto.h"
  4754. #include "endian.h"
  4755. #include "helpers.h"
  4756. #include "network.h"
  4757. #include "shared_globals.h"
  4758. /* Forwards */
  4759. static int checkRpcHeader(const RPC_HEADER *const Header, const BYTE desiredPacketType, const PRINTFUNC p);
  4760. /* Data definitions */
  4761. // All GUIDs are defined as BYTE[16] here. No big-endian/little-endian byteswapping required.
  4762. static const BYTE TransferSyntaxNDR32[] = {
  4763. 0x04, 0x5D, 0x88, 0x8A, 0xEB, 0x1C, 0xC9, 0x11, 0x9F, 0xE8, 0x08, 0x00, 0x2B, 0x10, 0x48, 0x60
  4764. };
  4765. static const BYTE InterfaceUuid[] = {
  4766. 0x75, 0x21, 0xc8, 0x51, 0x4e, 0x84, 0x50, 0x47, 0xB0, 0xD8, 0xEC, 0x25, 0x55, 0x55, 0xBC, 0x06
  4767. };
  4768. static const BYTE TransferSyntaxNDR64[] = {
  4769. 0x33, 0x05, 0x71, 0x71, 0xba, 0xbe, 0x37, 0x49, 0x83, 0x19, 0xb5, 0xdb, 0xef, 0x9c, 0xcc, 0x36
  4770. };
  4771. static const BYTE BindTimeFeatureNegotiation[] = {
  4772. 0x2c, 0x1c, 0xb7, 0x6c, 0x12, 0x98, 0x40, 0x45, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
  4773. };
  4774. //
  4775. // Dispatch RPC payload to kms.c
  4776. //
  4777. typedef int (*CreateResponse_t)(const void *const, void *const, const char* const);
  4778. static const struct {
  4779. unsigned int RequestSize;
  4780. CreateResponse_t CreateResponse;
  4781. } _Versions[] = {
  4782. { sizeof(REQUEST_V4), (CreateResponse_t) CreateResponseV4 },
  4783. { sizeof(REQUEST_V6), (CreateResponse_t) CreateResponseV6 },
  4784. { sizeof(REQUEST_V6), (CreateResponse_t) CreateResponseV6 }
  4785. };
  4786. RPC_FLAGS RpcFlags;
  4787. static int_fast8_t firstPacketSent;
  4788. //
  4789. // RPC request (server)
  4790. //
  4791. #if defined(_PEDANTIC) && !defined(NO_LOG)
  4792. static void CheckRpcRequest(const RPC_REQUEST64 *const Request, const unsigned int len, WORD* NdrCtx, WORD* Ndr64Ctx, WORD Ctx)
  4793. {
  4794. uint_fast8_t kmsMajorVersion;
  4795. uint32_t requestSize = Ctx != *Ndr64Ctx ? sizeof(RPC_REQUEST) : sizeof(RPC_REQUEST64);
  4796. if (len < requestSize)
  4797. {
  4798. logger("Fatal: RPC request (including header) must be at least %i bytes but is only %i bytes.\n",
  4799. (int)(sizeof(RPC_HEADER) + requestSize),
  4800. (int)(len + sizeof(RPC_HEADER))
  4801. );
  4802. return;
  4803. }
  4804. if (len < requestSize + sizeof(DWORD))
  4805. {
  4806. logger("Fatal: KMS Request too small to contain version info (less than 4 bytes).\n");
  4807. return;
  4808. }
  4809. if (Ctx != *Ndr64Ctx)
  4810. kmsMajorVersion = LE16(((WORD*)Request->Ndr.Data)[1]);
  4811. else
  4812. kmsMajorVersion = LE16(((WORD*)Request->Ndr64.Data)[1]);
  4813. if (kmsMajorVersion > 6)
  4814. {
  4815. logger("Fatal: KMSv%u is not supported.\n", (unsigned int)kmsMajorVersion);
  4816. }
  4817. else
  4818. {
  4819. if (len >_Versions[kmsMajorVersion].RequestSize + requestSize)
  4820. logger("Warning: %u excess bytes in RPC request.\n",
  4821. len - _Versions[kmsMajorVersion].RequestSize
  4822. );
  4823. }
  4824. if (Ctx != *Ndr64Ctx && Ctx != *NdrCtx)
  4825. logger("Warning: Context id should be %u (NDR32) or %u (NDR64) but is %u.\n",
  4826. (unsigned int)*NdrCtx,
  4827. (unsigned int)*Ndr64Ctx,
  4828. Ctx
  4829. );
  4830. if (Request->Opnum)
  4831. logger("Warning: OpNum should be 0 but is %u.\n",
  4832. (unsigned int)LE16(Request->Opnum)
  4833. );
  4834. if (LE32(Request->AllocHint) != len - sizeof(RPC_REQUEST) + sizeof(Request->Ndr))
  4835. logger("Warning: Allocation hint should be %u but is %u.\n",
  4836. len + sizeof(Request->Ndr),
  4837. LE32(Request->AllocHint)
  4838. );
  4839. if (Ctx != *Ndr64Ctx)
  4840. {
  4841. if (LE32(Request->Ndr.DataLength) != len - sizeof(RPC_REQUEST))
  4842. logger("Warning: NDR32 data length field should be %u but is %u.\n",
  4843. len - sizeof(RPC_REQUEST),
  4844. LE32(Request->Ndr.DataLength)
  4845. );
  4846. if (LE32(Request->Ndr.DataSizeIs) != len - sizeof(RPC_REQUEST))
  4847. logger("Warning: NDR32 data size field should be %u but is %u.\n",
  4848. len - sizeof(RPC_REQUEST),
  4849. LE32(Request->Ndr.DataSizeIs)
  4850. );
  4851. }
  4852. else
  4853. {
  4854. if (LE64(Request->Ndr64.DataLength) != len - sizeof(RPC_REQUEST64))
  4855. logger("Warning: NDR32 data length field should be %u but is %u.\n",
  4856. len - sizeof(RPC_REQUEST) + sizeof(Request->Ndr),
  4857. LE64(Request->Ndr64.DataLength)
  4858. );
  4859. if (LE64(Request->Ndr64.DataSizeIs) != len - sizeof(RPC_REQUEST64))
  4860. logger("Warning: NDR32 data size field should be %u but is %u.\n",
  4861. len - sizeof(RPC_REQUEST64),
  4862. LE64(Request->Ndr64.DataSizeIs)
  4863. );
  4864. }
  4865. }
  4866. #endif // defined(_PEDANTIC) && !defined(NO_LOG)
  4867. /*
  4868. * check RPC request for (somewhat) correct size
  4869. * allow any size that does not cause CreateResponse to fail badly
  4870. */
  4871. static unsigned int checkRpcRequestSize(const RPC_REQUEST64 *const Request, const unsigned int requestSize, WORD* NdrCtx, WORD* Ndr64Ctx)
  4872. {
  4873. WORD Ctx = LE16(Request->ContextId);
  4874. # if defined(_PEDANTIC) && !defined(NO_LOG)
  4875. CheckRpcRequest(Request, requestSize, NdrCtx, Ndr64Ctx, Ctx);
  4876. # endif // defined(_PEDANTIC) && !defined(NO_LOG)
  4877. // Anything that is smaller than a v4 request is illegal
  4878. if (requestSize < sizeof(REQUEST_V4) + (Ctx != *Ndr64Ctx ? sizeof(RPC_REQUEST) : sizeof(RPC_REQUEST64))) return 0;
  4879. // Get KMS major version
  4880. uint_fast16_t _v;
  4881. if (Ctx != *Ndr64Ctx)
  4882. _v = LE16(((WORD*)Request->Ndr.Data)[1]) - 4;
  4883. else
  4884. _v = LE16(((WORD*)Request->Ndr64.Data)[1]) - 4;
  4885. // Only KMS v4, v5 and v6 are supported
  4886. if (_v >= vlmcsd_countof(_Versions))
  4887. {
  4888. # ifndef NO_LOG
  4889. logger("Fatal: KMSv%i unsupported\n", _v + 4);
  4890. # endif // NO_LOG
  4891. return 0;
  4892. }
  4893. // Could check for equality but allow bigger requests to support buggy RPC clients (e.g. wine)
  4894. // Buffer overrun is check by caller.
  4895. return (requestSize >= _Versions[_v].RequestSize);
  4896. }
  4897. /*
  4898. * Handles the actual KMS request from the client.
  4899. * Calls KMS functions (CreateResponseV4 or CreateResponseV6) in kms.c
  4900. * Returns size of the KMS response packet or 0 on failure.
  4901. *
  4902. * The RPC packet size (excluding header) is actually in Response->AllocHint
  4903. */
  4904. static int rpcRequest(const RPC_REQUEST64 *const Request, RPC_RESPONSE64 *const Response, const DWORD RpcAssocGroup_unused, const SOCKET sock_unused, WORD* NdrCtx, WORD* Ndr64Ctx, BYTE packetType, const char* const ipstr)
  4905. {
  4906. uint_fast16_t _v;
  4907. int ResponseSize;
  4908. WORD Ctx = LE16(Request->ContextId);
  4909. BYTE* requestData;
  4910. BYTE* responseData;
  4911. BYTE* pRpcReturnCode;
  4912. int len;
  4913. if (Ctx != *Ndr64Ctx)
  4914. {
  4915. requestData = (BYTE*)&Request->Ndr.Data;
  4916. responseData = (BYTE*)&Response->Ndr.Data;
  4917. }
  4918. else
  4919. {
  4920. requestData = (BYTE*)&Request->Ndr64.Data;
  4921. responseData = (BYTE*)&Response->Ndr64.Data;
  4922. }
  4923. _v = LE16(((WORD*)requestData)[1]) - 4;
  4924. if (!(ResponseSize = _Versions[_v].CreateResponse(requestData, responseData, ipstr)))
  4925. {
  4926. return 0;
  4927. }
  4928. if (Ctx != *Ndr64Ctx)
  4929. {
  4930. Response->Ndr.DataSizeMax = LE32(0x00020000);
  4931. Response->Ndr.DataLength = Response->Ndr.DataSizeIs = LE32(ResponseSize);
  4932. len = ResponseSize + sizeof(Response->Ndr);
  4933. }
  4934. else
  4935. {
  4936. Response->Ndr64.DataSizeMax = LE64(0x00020000ULL);
  4937. Response->Ndr64.DataLength = Response->Ndr64.DataSizeIs = LE64((uint64_t)ResponseSize);
  4938. len = ResponseSize + sizeof(Response->Ndr64);
  4939. }
  4940. pRpcReturnCode = ((BYTE*)&Response->Ndr) + len;
  4941. UA32(pRpcReturnCode) = 0; //LE32 not needed for 0
  4942. len += sizeof(DWORD);
  4943. // Pad zeros to 32-bit align (seems not neccassary but Windows RPC does it this way)
  4944. int pad = ((~len & 3) + 1) & 3;
  4945. memset(pRpcReturnCode + sizeof(DWORD), 0, pad);
  4946. len += pad;
  4947. Response->AllocHint = LE32(len);
  4948. Response->ContextId = Request->ContextId;
  4949. *((WORD*)&Response->CancelCount) = 0; // CancelCount + Pad1
  4950. return len + 8;
  4951. }
  4952. #if defined(_PEDANTIC) && !defined(NO_LOG)
  4953. static void CheckRpcBindRequest(const RPC_BIND_REQUEST *const Request, const unsigned int len)
  4954. {
  4955. uint_fast8_t i, HasTransferSyntaxNDR32 = FALSE;
  4956. char guidBuffer1[GUID_STRING_LENGTH + 1], guidBuffer2[GUID_STRING_LENGTH + 1];
  4957. uint32_t CapCtxItems = (len - sizeof(*Request) + sizeof(Request->CtxItems)) / sizeof(Request->CtxItems);
  4958. DWORD NumCtxItems = LE32(Request->NumCtxItems);
  4959. if (NumCtxItems < CapCtxItems) // Can't be too small because already handled by RpcBindSize
  4960. logger("Warning: Excess bytes in RPC bind request.\n");
  4961. for (i = 0; i < NumCtxItems; i++)
  4962. {
  4963. if (!IsEqualGUID(&Request->CtxItems[i].InterfaceUUID, InterfaceUuid))
  4964. {
  4965. uuid2StringLE((GUID*)&Request->CtxItems[i].InterfaceUUID, guidBuffer1);
  4966. uuid2StringLE((GUID*)InterfaceUuid, guidBuffer2);
  4967. logger("Warning: Interface UUID is %s but should be %s in Ctx item %u.\n", guidBuffer1, guidBuffer2, (unsigned int)i);
  4968. }
  4969. if (Request->CtxItems[i].NumTransItems != LE16(1))
  4970. logger("Fatal: %u NDR32 transfer items detected in Ctx item %u, but only one is supported.\n",
  4971. (unsigned int)LE16(Request->CtxItems[i].NumTransItems), (unsigned int)i
  4972. );
  4973. if (Request->CtxItems[i].InterfaceVerMajor != LE16(1) || Request->CtxItems[i].InterfaceVerMinor != 0)
  4974. logger("Warning: NDR32 Interface version is %u.%u but should be 1.0.\n",
  4975. (unsigned int)LE16(Request->CtxItems[i].InterfaceVerMajor),
  4976. (unsigned int)LE16(Request->CtxItems[i].InterfaceVerMinor)
  4977. );
  4978. if (Request->CtxItems[i].ContextId != LE16((WORD)i))
  4979. logger("Warning: context id of Ctx item %u is %u.\n", (unsigned int)i, (unsigned int)Request->CtxItems[i].ContextId);
  4980. if ( IsEqualGUID((GUID*)TransferSyntaxNDR32, &Request->CtxItems[i].TransferSyntax) )
  4981. {
  4982. HasTransferSyntaxNDR32 = TRUE;
  4983. if (Request->CtxItems[i].SyntaxVersion != LE32(2))
  4984. logger("NDR32 transfer syntax version is %u but should be 2.\n", LE32(Request->CtxItems[i].SyntaxVersion));
  4985. }
  4986. else if ( IsEqualGUID((GUID*)TransferSyntaxNDR64, &Request->CtxItems[i].TransferSyntax) )
  4987. {
  4988. if (Request->CtxItems[i].SyntaxVersion != LE32(1))
  4989. logger("NDR64 transfer syntax version is %u but should be 1.\n", LE32(Request->CtxItems[i].SyntaxVersion));
  4990. }
  4991. else if (!memcmp(BindTimeFeatureNegotiation, (BYTE*)(&Request->CtxItems[i].TransferSyntax), 8))
  4992. {
  4993. if (Request->CtxItems[i].SyntaxVersion != LE32(1))
  4994. logger("BTFN syntax version is %u but should be 1.\n", LE32(Request->CtxItems[i].SyntaxVersion));
  4995. }
  4996. }
  4997. if (!HasTransferSyntaxNDR32)
  4998. logger("Warning: RPC bind request has no NDR32 CtxItem.\n");
  4999. }
  5000. #endif // defined(_PEDANTIC) && !defined(NO_LOG)
  5001. /*
  5002. * Check, if we receive enough bytes to return a valid RPC bind response
  5003. */
  5004. static unsigned int checkRpcBindSize(const RPC_BIND_REQUEST *const Request, const unsigned int RequestSize, WORD* NdrCtx, WORD* Ndr64Ctx)
  5005. {
  5006. if ( RequestSize < sizeof(RPC_BIND_REQUEST) ) return FALSE;
  5007. unsigned int _NumCtxItems = LE32(Request->NumCtxItems);
  5008. if ( RequestSize < sizeof(RPC_BIND_REQUEST) - sizeof(Request->CtxItems[0]) + _NumCtxItems * sizeof(Request->CtxItems[0]) ) return FALSE;
  5009. #if defined(_PEDANTIC) && !defined(NO_LOG)
  5010. CheckRpcBindRequest(Request, RequestSize);
  5011. #endif // defined(_PEDANTIC) && !defined(NO_LOG)
  5012. return TRUE;
  5013. }
  5014. /*
  5015. * Accepts a bind or alter context request from the client and composes the bind response.
  5016. * Needs the socket because the tcp port number is part of the response.
  5017. * len is not used here.
  5018. *
  5019. * Returns TRUE on success.
  5020. */
  5021. static int rpcBind(const RPC_BIND_REQUEST *const Request, RPC_BIND_RESPONSE* Response, const DWORD RpcAssocGroup, const SOCKET sock, WORD* NdrCtx, WORD* Ndr64Ctx, BYTE packetType, const char* const ipstr_unused)
  5022. {
  5023. unsigned int i, _st = FALSE;
  5024. DWORD numCtxItems = LE32(Request->NumCtxItems);
  5025. int_fast8_t IsNDR64possible = FALSE;
  5026. uint_fast8_t portNumberSize;
  5027. socklen_t socklen;
  5028. struct sockaddr_storage addr;
  5029. // M$ RPC does not do this. Pad bytes contain apparently random data
  5030. // memset(Response->SecondaryAddress, 0, sizeof(Response->SecondaryAddress));
  5031. socklen = sizeof addr;
  5032. if (
  5033. packetType == RPC_PT_ALTERCONTEXT_REQ ||
  5034. getsockname(sock, (struct sockaddr*)&addr, &socklen) ||
  5035. getnameinfo((struct sockaddr*)&addr, socklen, NULL, 0, (char*)Response->SecondaryAddress, sizeof(Response->SecondaryAddress), NI_NUMERICSERV))
  5036. {
  5037. portNumberSize = Response->SecondaryAddressLength = 0;
  5038. }
  5039. else
  5040. {
  5041. portNumberSize = strlen((char*)Response->SecondaryAddress) + 1;
  5042. Response->SecondaryAddressLength = LE16(portNumberSize);
  5043. }
  5044. Response->MaxXmitFrag = Request->MaxXmitFrag;
  5045. Response->MaxRecvFrag = Request->MaxRecvFrag;
  5046. Response->AssocGroup = LE32(RpcAssocGroup);
  5047. // This is really ugly (but efficient) code to support padding after the secondary address field
  5048. if (portNumberSize < 3)
  5049. {
  5050. Response = (RPC_BIND_RESPONSE*)((BYTE*)Response - 4);
  5051. }
  5052. Response->NumResults = Request->NumCtxItems;
  5053. if (UseRpcNDR64)
  5054. {
  5055. for (i = 0; i < numCtxItems; i++)
  5056. {
  5057. if ( IsEqualGUID((GUID*)TransferSyntaxNDR32, &Request->CtxItems[i].TransferSyntax) )
  5058. {
  5059. /*if (packetType == RPC_PT_BIND_REQ)*/
  5060. *NdrCtx = LE16(Request->CtxItems[i].ContextId);
  5061. }
  5062. if ( IsEqualGUID((GUID*)TransferSyntaxNDR64, &Request->CtxItems[i].TransferSyntax) )
  5063. {
  5064. IsNDR64possible = TRUE;
  5065. /*if (packetType == RPC_PT_BIND_REQ)*/
  5066. *Ndr64Ctx = LE16(Request->CtxItems[i].ContextId);
  5067. }
  5068. }
  5069. }
  5070. for (i = 0; i < numCtxItems; i++)
  5071. {
  5072. memset(&Response->Results[i].TransferSyntax, 0, sizeof(GUID));
  5073. if ( !IsNDR64possible && IsEqualGUID((GUID*)TransferSyntaxNDR32, &Request->CtxItems[i].TransferSyntax) )
  5074. {
  5075. Response->Results[i].SyntaxVersion = LE32(2);
  5076. Response->Results[i].AckResult =
  5077. Response->Results[i].AckReason = RPC_BIND_ACCEPT;
  5078. memcpy(&Response->Results[i].TransferSyntax, TransferSyntaxNDR32, sizeof(GUID));
  5079. _st = TRUE;
  5080. }
  5081. else if ( IsNDR64possible && IsEqualGUID((GUID*)TransferSyntaxNDR64, &Request->CtxItems[i].TransferSyntax) )
  5082. {
  5083. Response->Results[i].SyntaxVersion = LE32(1);
  5084. Response->Results[i].AckResult =
  5085. Response->Results[i].AckReason = RPC_BIND_ACCEPT;
  5086. memcpy(&Response->Results[i].TransferSyntax, TransferSyntaxNDR64, sizeof(GUID));
  5087. _st = TRUE;
  5088. }
  5089. else if ( UseRpcBTFN && !memcmp(BindTimeFeatureNegotiation, (BYTE*)(&Request->CtxItems[i].TransferSyntax), 8) )
  5090. {
  5091. Response->Results[i].SyntaxVersion = 0;
  5092. Response->Results[i].AckResult = RPC_BIND_ACK;
  5093. // Features requested are actually encoded in the GUID
  5094. Response->Results[i].AckReason =
  5095. ((WORD*)(&Request->CtxItems[i].TransferSyntax))[4] &
  5096. (RPC_BTFN_SEC_CONTEXT_MULTIPLEX | RPC_BTFN_KEEP_ORPHAN);
  5097. }
  5098. else
  5099. {
  5100. Response->Results[i].SyntaxVersion = 0;
  5101. Response->Results[i].AckResult =
  5102. Response->Results[i].AckReason = RPC_BIND_NACK; // Unsupported
  5103. }
  5104. }
  5105. if ( !_st ) return 0;
  5106. return sizeof(RPC_BIND_RESPONSE) + numCtxItems * sizeof(((RPC_BIND_RESPONSE *)0)->Results[0]) - (portNumberSize < 3 ? 4 : 0);
  5107. }
  5108. //
  5109. // Main RPC handling routine
  5110. //
  5111. typedef unsigned int (*GetResponseSize_t)(const void *const request, const unsigned int requestSize, WORD* NdrCtx, WORD* Ndr64Ctx);
  5112. typedef int (*GetResponse_t)(const void* const request, void* response, const DWORD rpcAssocGroup, const SOCKET socket, WORD* NdrCtx, WORD* Ndr64Ctx, BYTE packetType, const char* const ipstr);
  5113. static const struct {
  5114. BYTE ResponsePacketType;
  5115. GetResponseSize_t CheckRequestSize;
  5116. GetResponse_t GetResponse;
  5117. }
  5118. _Actions[] = {
  5119. { RPC_PT_BIND_ACK, (GetResponseSize_t)checkRpcBindSize, (GetResponse_t) rpcBind },
  5120. { RPC_PT_RESPONSE, (GetResponseSize_t)checkRpcRequestSize, (GetResponse_t) rpcRequest },
  5121. { RPC_PT_ALTERCONTEXT_ACK, (GetResponseSize_t)checkRpcBindSize, (GetResponse_t) rpcBind },
  5122. };
  5123. /*
  5124. * This is the main RPC server loop. Returns after KMS request has been serviced
  5125. * or a timeout has occured.
  5126. */
  5127. void rpcServer(const SOCKET sock, const DWORD RpcAssocGroup, const char* const ipstr)
  5128. {
  5129. RPC_HEADER rpcRequestHeader;
  5130. WORD NdrCtx = INVALID_NDR_CTX, Ndr64Ctx = INVALID_NDR_CTX;
  5131. randomNumberInit();
  5132. while (_recv(sock, &rpcRequestHeader, sizeof(rpcRequestHeader)))
  5133. {
  5134. //int_fast8_t _st;
  5135. unsigned int request_len, response_len;
  5136. uint_fast8_t _a;
  5137. #if defined(_PEDANTIC) && !defined(NO_LOG)
  5138. checkRpcHeader(&rpcRequestHeader, rpcRequestHeader.PacketType, &logger);
  5139. #endif // defined(_PEDANTIC) && !defined(NO_LOG)
  5140. switch (rpcRequestHeader.PacketType)
  5141. {
  5142. case RPC_PT_BIND_REQ: _a = 0; break;
  5143. case RPC_PT_REQUEST: _a = 1; break;
  5144. case RPC_PT_ALTERCONTEXT_REQ: _a = 2; break;
  5145. default: return;
  5146. }
  5147. request_len = LE16(rpcRequestHeader.FragLength) - sizeof(rpcRequestHeader);
  5148. BYTE requestBuffer[MAX_REQUEST_SIZE + sizeof(RPC_RESPONSE64)];
  5149. BYTE responseBuffer[MAX_RESPONSE_SIZE + sizeof(RPC_HEADER) + sizeof(RPC_RESPONSE64)];
  5150. RPC_HEADER *rpcResponseHeader = (RPC_HEADER *)responseBuffer;
  5151. RPC_RESPONSE* rpcResponse = (RPC_RESPONSE*)(responseBuffer + sizeof(rpcRequestHeader));
  5152. // The request is larger than the buffer size
  5153. if (request_len > MAX_REQUEST_SIZE + sizeof(RPC_REQUEST64)) return;
  5154. // Unable to receive the complete request
  5155. if (!_recv(sock, requestBuffer, request_len)) return;
  5156. // Request is invalid
  5157. if (!_Actions[_a].CheckRequestSize(requestBuffer, request_len, &NdrCtx, &Ndr64Ctx)) return;
  5158. // Unable to create a valid response from request
  5159. if (!(response_len = _Actions[_a].GetResponse(requestBuffer, rpcResponse, RpcAssocGroup, sock, &NdrCtx, &Ndr64Ctx, rpcRequestHeader.PacketType, ipstr))) return;
  5160. response_len += sizeof(RPC_HEADER);
  5161. memcpy(rpcResponseHeader, &rpcRequestHeader, sizeof(RPC_HEADER));
  5162. rpcResponseHeader->FragLength = LE16(response_len);
  5163. rpcResponseHeader->PacketType = _Actions[_a].ResponsePacketType;
  5164. if (rpcResponseHeader->PacketType == RPC_PT_ALTERCONTEXT_ACK)
  5165. rpcResponseHeader->PacketFlags = RPC_PF_FIRST | RPC_PF_LAST;
  5166. if (!_send(sock, responseBuffer, response_len)) return;
  5167. if (DisconnectImmediately && rpcResponseHeader->PacketType == RPC_PT_RESPONSE)
  5168. shutdown(sock, VLMCSD_SHUT_RDWR);
  5169. }
  5170. }
  5171. /* RPC client functions */
  5172. static DWORD CallId = 2; // M$ starts with CallId 2. So we do the same.
  5173. /*
  5174. * Checks RPC header. Returns 0 on success.
  5175. * This is mainly for debugging a non Microsoft KMS server that uses its own RPC code.
  5176. */
  5177. static int checkRpcHeader(const RPC_HEADER *const Header, const BYTE desiredPacketType, const PRINTFUNC p)
  5178. {
  5179. int status = 0;
  5180. if (Header->PacketType != desiredPacketType)
  5181. {
  5182. p("Fatal: Received wrong RPC packet type. Expected %u but got %u\n",
  5183. (uint32_t)desiredPacketType,
  5184. Header->PacketType
  5185. );
  5186. status = !0;
  5187. }
  5188. if (Header->DataRepresentation != BE32(0x10000000))
  5189. {
  5190. p("Fatal: RPC response does not conform to Microsoft's limited support of DCE RPC\n");
  5191. status = !0;
  5192. }
  5193. if (Header->AuthLength != 0)
  5194. {
  5195. p("Fatal: RPC response requests authentication\n");
  5196. status = !0;
  5197. }
  5198. // vlmcsd does not support fragmented packets (not yet neccassary)
  5199. if ( (Header->PacketFlags & (RPC_PF_FIRST | RPC_PF_LAST)) != (RPC_PF_FIRST | RPC_PF_LAST) )
  5200. {
  5201. p("Fatal: RPC packet flags RPC_PF_FIRST and RPC_PF_LAST are not both set.\n");
  5202. status = !0;
  5203. }
  5204. if (Header->PacketFlags & RPC_PF_CANCEL_PENDING) p("Warning: %s should not be set\n", "RPC_PF_CANCEL_PENDING");
  5205. if (Header->PacketFlags & RPC_PF_RESERVED) p("Warning: %s should not be set\n", "RPC_PF_RESERVED");
  5206. if (Header->PacketFlags & RPC_PF_NOT_EXEC) p("Warning: %s should not be set\n", "RPC_PF_NOT_EXEC");
  5207. if (Header->PacketFlags & RPC_PF_MAYBE) p("Warning: %s should not be set\n", "RPC_PF_MAYBE");
  5208. if (Header->PacketFlags & RPC_PF_OBJECT) p("Warning: %s should not be set\n", "RPC_PF_OBJECT");
  5209. if (Header->VersionMajor != 5 || Header->VersionMinor != 0)
  5210. {
  5211. p("Fatal: Expected RPC version 5.0 and got %u.%u\n", Header->VersionMajor, Header->VersionMinor);
  5212. status = !0;
  5213. }
  5214. return status;
  5215. }
  5216. /*
  5217. * Checks an RPC response header. Does basic header checks by calling checkRpcHeader()
  5218. * and then does additional checks if response header complies with the respective request header.
  5219. * PRINTFUNC p can be anything that has the same prototype as printf.
  5220. * Returns 0 on success.
  5221. */
  5222. static int checkRpcResponseHeader(const RPC_HEADER *const ResponseHeader, const RPC_HEADER *const RequestHeader, const BYTE desiredPacketType, const PRINTFUNC p)
  5223. {
  5224. static int_fast8_t WineBugDetected = FALSE;
  5225. int status = checkRpcHeader(ResponseHeader, desiredPacketType, p);
  5226. if (desiredPacketType == RPC_PT_BIND_ACK)
  5227. {
  5228. if ((ResponseHeader->PacketFlags & RPC_PF_MULTIPLEX) != (RequestHeader->PacketFlags & RPC_PF_MULTIPLEX))
  5229. {
  5230. p("Warning: RPC_PF_MULTIPLEX of RPC request and response should match\n");
  5231. }
  5232. }
  5233. else
  5234. {
  5235. if (ResponseHeader->PacketFlags & RPC_PF_MULTIPLEX)
  5236. {
  5237. p("Warning: %s should not be set\n", "RPC_PF_MULTIPLEX");
  5238. }
  5239. }
  5240. if (!status && ResponseHeader->CallId == LE32(1))
  5241. {
  5242. if (!WineBugDetected)
  5243. {
  5244. p("Warning: Buggy RPC of Wine detected. Call Id of Response is always 1\n");
  5245. WineBugDetected = TRUE;
  5246. }
  5247. }
  5248. else if (ResponseHeader->CallId != RequestHeader->CallId)
  5249. {
  5250. p("Fatal: Sent Call Id %u but received answer for Call Id %u\n",
  5251. (uint32_t)LE32(RequestHeader->CallId),
  5252. (uint32_t)LE32(ResponseHeader->CallId)
  5253. );
  5254. status = !0;
  5255. }
  5256. return status;
  5257. }
  5258. /*
  5259. * Initializes an RPC request header as needed for KMS, i.e. packet always fits in one fragment.
  5260. * size cannot be greater than fragment length negotiated during RPC bind.
  5261. */
  5262. static void createRpcRequestHeader(RPC_HEADER* RequestHeader, BYTE packetType, WORD size)
  5263. {
  5264. RequestHeader->PacketType = packetType;
  5265. RequestHeader->PacketFlags = RPC_PF_FIRST | RPC_PF_LAST;
  5266. RequestHeader->VersionMajor = 5;
  5267. RequestHeader->VersionMinor = 0;
  5268. RequestHeader->AuthLength = 0;
  5269. RequestHeader->DataRepresentation = BE32(0x10000000); // Little endian, ASCII charset, IEEE floating point
  5270. RequestHeader->CallId = LE32(CallId);
  5271. RequestHeader->FragLength = LE16(size);
  5272. }
  5273. /*
  5274. * Sends a KMS request via RPC and receives a response.
  5275. * Parameters are raw (encrypted) reqeuests / responses.
  5276. * Returns 0 on success.
  5277. */
  5278. RpcStatus rpcSendRequest(const RpcCtx sock, const BYTE *const KmsRequest, const size_t requestSize, BYTE **KmsResponse, size_t *const responseSize)
  5279. {
  5280. #define MAX_EXCESS_BYTES 16
  5281. RPC_HEADER *RequestHeader, ResponseHeader;
  5282. RPC_REQUEST64 *RpcRequest;
  5283. RPC_RESPONSE64 _Response;
  5284. int status = 0;
  5285. int_fast8_t useNdr64 = UseRpcNDR64 && firstPacketSent;
  5286. size_t size = sizeof(RPC_HEADER) + (useNdr64 ? sizeof(RPC_REQUEST64) : sizeof(RPC_REQUEST)) + requestSize;
  5287. size_t responseSize2;
  5288. *KmsResponse = NULL;
  5289. BYTE *_Request = (BYTE*)vlmcsd_malloc(size);
  5290. RequestHeader = (RPC_HEADER*)_Request;
  5291. RpcRequest = (RPC_REQUEST64*)(_Request + sizeof(RPC_HEADER));
  5292. createRpcRequestHeader(RequestHeader, RPC_PT_REQUEST, size);
  5293. // Increment CallId for next Request
  5294. CallId++;
  5295. RpcRequest->Opnum = 0;
  5296. if (useNdr64)
  5297. {
  5298. RpcRequest->ContextId = LE16(1); // We negotiate NDR64 always as context 1
  5299. RpcRequest->AllocHint = LE32(requestSize + sizeof(RpcRequest->Ndr64));
  5300. RpcRequest->Ndr64.DataLength = LE64((uint64_t)requestSize);
  5301. RpcRequest->Ndr64.DataSizeIs = LE64((uint64_t)requestSize);
  5302. memcpy(RpcRequest->Ndr64.Data, KmsRequest, requestSize);
  5303. }
  5304. else
  5305. {
  5306. RpcRequest->ContextId = 0; // We negotiate NDR32 always as context 0
  5307. RpcRequest->AllocHint = LE32(requestSize + sizeof(RpcRequest->Ndr));
  5308. RpcRequest->Ndr.DataLength = LE32(requestSize);
  5309. RpcRequest->Ndr.DataSizeIs = LE32(requestSize);
  5310. memcpy(RpcRequest->Ndr.Data, KmsRequest, requestSize);
  5311. }
  5312. for(;;)
  5313. {
  5314. int bytesread;
  5315. if (!_send(sock, _Request, size))
  5316. {
  5317. errorout("\nFatal: Could not send RPC request\n");
  5318. status = !0;
  5319. break;
  5320. }
  5321. if (!_recv(sock, &ResponseHeader, sizeof(RPC_HEADER)))
  5322. {
  5323. errorout("\nFatal: No RPC response received from server\n");
  5324. status = !0;
  5325. break;
  5326. }
  5327. if ((status = checkRpcResponseHeader(&ResponseHeader, RequestHeader, RPC_PT_RESPONSE, &errorout))) break;
  5328. size = useNdr64 ? sizeof(RPC_RESPONSE64) : sizeof(RPC_RESPONSE);
  5329. if (size > LE16(ResponseHeader.FragLength) - sizeof(ResponseHeader))
  5330. size = LE16(ResponseHeader.FragLength) - sizeof(ResponseHeader);
  5331. if (!_recv(sock, &_Response, size))
  5332. {
  5333. errorout("\nFatal: RPC response is incomplete\n");
  5334. status = !0;
  5335. break;
  5336. }
  5337. if (_Response.CancelCount != 0)
  5338. {
  5339. errorout("\nFatal: RPC response cancel count is not 0\n");
  5340. status = !0;
  5341. }
  5342. if (_Response.ContextId != (useNdr64 ? LE16(1) : 0))
  5343. {
  5344. errorout("\nFatal: RPC response context id %u is not bound\n", (unsigned int)LE16(_Response.ContextId));
  5345. status = !0;
  5346. }
  5347. int_fast8_t sizesMatch;
  5348. if (useNdr64)
  5349. {
  5350. *responseSize = (size_t)LE64(_Response.Ndr64.DataLength);
  5351. responseSize2 = (size_t)LE64(_Response.Ndr64.DataSizeIs);
  5352. if (!*responseSize || !_Response.Ndr64.DataSizeMax)
  5353. {
  5354. status = (int)LE32(_Response.Ndr64.status);
  5355. break;
  5356. }
  5357. sizesMatch = (size_t)LE64(_Response.Ndr64.DataLength) == responseSize2;
  5358. }
  5359. else
  5360. {
  5361. *responseSize = (size_t)LE32(_Response.Ndr.DataLength);
  5362. responseSize2 = (size_t)LE32(_Response.Ndr.DataSizeIs);
  5363. if (!*responseSize || !_Response.Ndr.DataSizeMax)
  5364. {
  5365. status = (int)LE32(_Response.Ndr.status);
  5366. break;
  5367. }
  5368. sizesMatch = (size_t)LE32(_Response.Ndr.DataLength) == responseSize2;
  5369. }
  5370. if (!sizesMatch)
  5371. {
  5372. errorout("\nFatal: NDR data length (%u) does not match NDR data size (%u)\n",
  5373. (uint32_t)*responseSize,
  5374. (uint32_t)LE32(_Response.Ndr.DataSizeIs)
  5375. );
  5376. status = !0;
  5377. }
  5378. *KmsResponse = (BYTE*)vlmcsd_malloc(*responseSize + MAX_EXCESS_BYTES);
  5379. // If RPC stub is too short, assume missing bytes are zero (same ill behavior as MS RPC)
  5380. memset(*KmsResponse, 0, *responseSize + MAX_EXCESS_BYTES);
  5381. // Read up to 16 bytes more than bytes expected to detect faulty KMS emulators
  5382. if ((bytesread = recv(sock, (char*)*KmsResponse, *responseSize + MAX_EXCESS_BYTES, 0)) < (int)*responseSize)
  5383. {
  5384. errorout("\nFatal: No or incomplete KMS response received. Required %u bytes but only got %i\n",
  5385. (uint32_t)*responseSize,
  5386. (int32_t)(bytesread < 0 ? 0 : bytesread)
  5387. );
  5388. status = !0;
  5389. break;
  5390. }
  5391. DWORD *pReturnCode;
  5392. size_t len = *responseSize + (useNdr64 ? sizeof(_Response.Ndr64) : sizeof(_Response.Ndr)) + sizeof(*pReturnCode);
  5393. size_t pad = ((~len & 3) + 1) & 3;
  5394. if (len + pad != LE32(_Response.AllocHint))
  5395. {
  5396. errorout("\nWarning: RPC stub size is %u, should be %u (probably incorrect padding)\n", (uint32_t)LE32(_Response.AllocHint), (uint32_t)(len + pad));
  5397. }
  5398. else
  5399. {
  5400. size_t i;
  5401. for (i = 0; i < pad; i++)
  5402. {
  5403. if (*(*KmsResponse + *responseSize + sizeof(*pReturnCode) + i))
  5404. {
  5405. errorout("\nWarning: RPC stub data not padded to zeros according to Microsoft standard\n");
  5406. break;
  5407. }
  5408. }
  5409. }
  5410. pReturnCode = (DWORD*)(*KmsResponse + *responseSize + pad);
  5411. status = LE32(UA32(pReturnCode));
  5412. if (status) errorout("\nWarning: RPC stub data reported Error %u\n", (uint32_t)status);
  5413. break;
  5414. }
  5415. free(_Request);
  5416. firstPacketSent = TRUE;
  5417. return status;
  5418. #undef MAX_EXCESS_BYTES
  5419. }
  5420. static int_fast8_t IsNullGuid(BYTE* guidPtr)
  5421. {
  5422. int_fast8_t i;
  5423. for (i = 0; i < 16; i++)
  5424. {
  5425. if (guidPtr[i]) return FALSE;
  5426. }
  5427. return TRUE;
  5428. }
  5429. /*
  5430. * Perform RPC client bind. Accepts a connected client socket.
  5431. * Returns 0 on success. RPC binding is required before any payload can be
  5432. * exchanged. It negotiates about protocol details.
  5433. */
  5434. RpcStatus rpcBindOrAlterClientContext(const RpcCtx sock, BYTE packetType, const int_fast8_t verbose)
  5435. {
  5436. RPC_HEADER *RequestHeader, ResponseHeader;
  5437. RPC_BIND_REQUEST *bindRequest;
  5438. RPC_BIND_RESPONSE *bindResponse;
  5439. int status;
  5440. WORD ctxItems = 1 + (packetType == RPC_PT_BIND_REQ ? UseRpcNDR64 + UseRpcBTFN : 0);
  5441. size_t rpcBindSize = (sizeof(RPC_HEADER) + sizeof(RPC_BIND_REQUEST) + (ctxItems - 1) * sizeof(bindRequest->CtxItems[0]));
  5442. WORD ctxIndex = 0;
  5443. WORD i;
  5444. WORD CtxBTFN = (WORD)~0, CtxNDR64 = (WORD)~0;
  5445. BYTE _Request[rpcBindSize];
  5446. RequestHeader = (RPC_HEADER*)_Request;
  5447. bindRequest = (RPC_BIND_REQUEST* )(_Request + sizeof(RPC_HEADER));
  5448. createRpcRequestHeader(RequestHeader, packetType, rpcBindSize);
  5449. RequestHeader->PacketFlags |= UseMultiplexedRpc ? RPC_PF_MULTIPLEX : 0;
  5450. bindRequest->AssocGroup = 0;
  5451. bindRequest->MaxRecvFrag = bindRequest->MaxXmitFrag = LE16(5840);
  5452. bindRequest->NumCtxItems = LE32(ctxItems);
  5453. // data that is identical in all Ctx items
  5454. for (i = 0; i < ctxItems; i++)
  5455. {
  5456. bindRequest->CtxItems[i].ContextId = LE16(i);
  5457. bindRequest->CtxItems[i].InterfaceVerMajor = LE16(1);
  5458. bindRequest->CtxItems[i].InterfaceVerMinor = 0;
  5459. bindRequest->CtxItems[i].NumTransItems = LE16(1);
  5460. bindRequest->CtxItems[i].SyntaxVersion = i ? LE32(1) : LE32(2);
  5461. memcpy(&bindRequest->CtxItems[i].InterfaceUUID, InterfaceUuid, sizeof(GUID));
  5462. }
  5463. memcpy(&bindRequest->CtxItems[0].TransferSyntax, TransferSyntaxNDR32, sizeof(GUID));
  5464. if (UseRpcNDR64 && packetType == RPC_PT_BIND_REQ)
  5465. {
  5466. memcpy(&bindRequest->CtxItems[++ctxIndex].TransferSyntax, TransferSyntaxNDR64, sizeof(GUID));
  5467. CtxNDR64 = ctxIndex;
  5468. }
  5469. if (UseRpcBTFN && packetType == RPC_PT_BIND_REQ)
  5470. {
  5471. memcpy(&bindRequest->CtxItems[++ctxIndex].TransferSyntax, BindTimeFeatureNegotiation, sizeof(GUID));
  5472. CtxBTFN = ctxIndex;
  5473. }
  5474. if (!_send(sock, _Request, rpcBindSize))
  5475. {
  5476. errorout("\nFatal: Sending RPC bind request failed\n");
  5477. return !0;
  5478. }
  5479. if (!_recv(sock, &ResponseHeader, sizeof(RPC_HEADER)))
  5480. {
  5481. errorout("\nFatal: Did not receive a response from server\n");
  5482. return !0;
  5483. }
  5484. if ((status = checkRpcResponseHeader
  5485. (
  5486. &ResponseHeader,
  5487. RequestHeader,
  5488. packetType == RPC_PT_BIND_REQ ? RPC_PT_BIND_ACK : RPC_PT_ALTERCONTEXT_ACK,
  5489. &errorout
  5490. )))
  5491. {
  5492. return status;
  5493. }
  5494. bindResponse = (RPC_BIND_RESPONSE*)vlmcsd_malloc(LE16(ResponseHeader.FragLength) - sizeof(RPC_HEADER));
  5495. BYTE* bindResponseBytePtr = (BYTE*)bindResponse;
  5496. if (!_recv(sock, bindResponse, LE16(ResponseHeader.FragLength) - sizeof(RPC_HEADER)))
  5497. {
  5498. errorout("\nFatal: Incomplete RPC bind acknowledgement received\n");
  5499. free(bindResponseBytePtr);
  5500. return !0;
  5501. }
  5502. else
  5503. {
  5504. /*
  5505. * checking, whether a bind or alter context response is as expected.
  5506. * This check is very strict and checks whether a KMS emulator behaves exactly the same way
  5507. * as Microsoft's RPC does.
  5508. */
  5509. status = 0;
  5510. if (bindResponse->SecondaryAddressLength < LE16(3))
  5511. bindResponse = (RPC_BIND_RESPONSE*)(bindResponseBytePtr - 4);
  5512. if (bindResponse->NumResults != bindRequest->NumCtxItems)
  5513. {
  5514. errorout("\nFatal: Expected %u CTX items but got %u\n",
  5515. (uint32_t)LE32(bindRequest->NumCtxItems),
  5516. (uint32_t)LE32(bindResponse->NumResults)
  5517. );
  5518. status = !0;
  5519. }
  5520. for (i = 0; i < ctxItems; i++)
  5521. {
  5522. const char* transferSyntaxName =
  5523. i == CtxBTFN ? "BTFN" : i == CtxNDR64 ? "NDR64" : "NDR32";
  5524. if (bindResponse->Results[i].AckResult == RPC_BIND_NACK) // transfer syntax was declined
  5525. {
  5526. if (!IsNullGuid((BYTE*)&bindResponse->Results[i].TransferSyntax))
  5527. {
  5528. errorout(
  5529. "\nWarning: Rejected transfer syntax %s did not return NULL Guid\n",
  5530. transferSyntaxName
  5531. );
  5532. }
  5533. if (bindResponse->Results[i].SyntaxVersion)
  5534. {
  5535. errorout(
  5536. "\nWarning: Rejected transfer syntax %s did not return syntax version 0 but %u\n",
  5537. transferSyntaxName,
  5538. LE32(bindResponse->Results[i].SyntaxVersion)
  5539. );
  5540. }
  5541. if (bindResponse->Results[i].AckReason == RPC_ABSTRACTSYNTAX_UNSUPPORTED)
  5542. {
  5543. errorout(
  5544. "\nWarning: Transfer syntax %s does not support KMS activation\n",
  5545. transferSyntaxName
  5546. );
  5547. }
  5548. else if (bindResponse->Results[i].AckReason != RPC_SYNTAX_UNSUPPORTED)
  5549. {
  5550. errorout(
  5551. "\nWarning: Rejected transfer syntax %s did not return ack reason RPC_SYNTAX_UNSUPPORTED\n",
  5552. transferSyntaxName
  5553. );
  5554. }
  5555. continue;
  5556. }
  5557. if (i == CtxBTFN) // BTFN
  5558. {
  5559. if (bindResponse->Results[i].AckResult != RPC_BIND_ACK)
  5560. {
  5561. errorout("\nWarning: BTFN did not respond with RPC_BIND_ACK or RPC_BIND_NACK\n");
  5562. }
  5563. if (bindResponse->Results[i].AckReason != LE16(3))
  5564. {
  5565. errorout("\nWarning: BTFN did not return expected feature mask 0x3 but 0x%X\n", (unsigned int)LE16(bindResponse->Results[i].AckReason));
  5566. }
  5567. if (verbose) printf("... BTFN ");
  5568. RpcFlags.HasBTFN = TRUE;
  5569. continue;
  5570. }
  5571. // NDR32 or NDR64 Ctx
  5572. if (bindResponse->Results[i].AckResult != RPC_BIND_ACCEPT)
  5573. {
  5574. errorout(
  5575. "\nFatal: transfer syntax %s returned an invalid status, neither RPC_BIND_ACCEPT nor RPC_BIND_NACK\n",
  5576. transferSyntaxName
  5577. );
  5578. status = !0;
  5579. }
  5580. if (!IsEqualGUID(&bindResponse->Results[i].TransferSyntax, &bindRequest->CtxItems[i].TransferSyntax))
  5581. {
  5582. errorout(
  5583. "\nFatal: Transfer syntax of RPC bind request and response does not match\n"
  5584. );
  5585. status = !0;
  5586. }
  5587. if (bindResponse->Results[i].SyntaxVersion != bindRequest->CtxItems[i].SyntaxVersion)
  5588. {
  5589. errorout("\nFatal: Expected transfer syntax version %u for %s but got %u\n",
  5590. (uint32_t)LE32(bindRequest->CtxItems[0].SyntaxVersion),
  5591. transferSyntaxName,
  5592. (uint32_t)LE32(bindResponse->Results[0].SyntaxVersion)
  5593. );
  5594. status = !0;
  5595. }
  5596. // The ack reason field is actually undefined here but Microsoft sets this to 0
  5597. if (bindResponse->Results[i].AckReason != 0)
  5598. {
  5599. errorout(
  5600. "\nWarning: Ack reason should be 0 but is %u\n",
  5601. LE16(bindResponse->Results[i].AckReason)
  5602. );
  5603. }
  5604. if (!status)
  5605. {
  5606. if (i == CtxNDR64)
  5607. {
  5608. RpcFlags.HasNDR64 = TRUE;
  5609. if (verbose) printf("... NDR64 ");
  5610. }
  5611. if (!i)
  5612. {
  5613. RpcFlags.HasNDR32 = TRUE;
  5614. if (verbose) printf("... NDR32 ");
  5615. }
  5616. }
  5617. }
  5618. }
  5619. free(bindResponseBytePtr);
  5620. if (!RpcFlags.HasNDR64 && !RpcFlags.HasNDR32)
  5621. {
  5622. errorout("\nFatal: Could neither negotiate NDR32 nor NDR64 with the RPC server\n");
  5623. status = !0;
  5624. }
  5625. return status;
  5626. }
  5627. RpcStatus rpcBindClient(const RpcCtx sock, const int_fast8_t verbose)
  5628. {
  5629. firstPacketSent = FALSE;
  5630. RpcFlags.mask = 0;
  5631. RpcStatus status =
  5632. rpcBindOrAlterClientContext(sock, RPC_PT_BIND_REQ, verbose);
  5633. if (status) return status;
  5634. if (!RpcFlags.HasNDR32)
  5635. status = rpcBindOrAlterClientContext(sock, RPC_PT_ALTERCONTEXT_REQ, verbose);
  5636. return status;
  5637. }
  5638. #endif // USE_MSRPC
  5639. #ifndef CONFIG
  5640. #define CONFIG "config.h"
  5641. #endif // CONFIG
  5642. #include CONFIG
  5643. #if !defined(_CRYPTO_OPENSSL) && !defined(_CRYPTO_POLARSSL) && !defined(_CRYPTO_WINDOWS)
  5644. #include "crypto_internal.h"
  5645. #include "endian.h"
  5646. #define F0(x, y, z) ( ((x) & (y)) | (~(x) & (z)) )
  5647. #define F1(x, y, z) ( ((x) & (y)) | ((x) & (z)) | ((y) & (z)) )
  5648. #define SI1(x) ( ROR32(x, 2 ) ^ ROR32(x, 13) ^ ROR32(x, 22) )
  5649. #define SI2(x) ( ROR32(x, 6 ) ^ ROR32(x, 11) ^ ROR32(x, 25) )
  5650. #define SI3(x) ( ROR32(x, 7 ) ^ ROR32(x, 18) ^ ((x) >> 3 ) )
  5651. #define SI4(x) ( ROR32(x, 17) ^ ROR32(x, 19) ^ ((x) >> 10) )
  5652. static const DWORD k[] = {
  5653. 0x428A2F98, 0x71374491, 0xB5C0FBCF, 0xE9B5DBA5, 0x3956C25B, 0x59F111F1,
  5654. 0x923F82A4, 0xAB1C5ED5, 0xD807AA98, 0x12835B01, 0x243185BE, 0x550C7DC3,
  5655. 0x72BE5D74, 0x80DEB1FE, 0x9BDC06A7, 0xC19BF174, 0xE49B69C1, 0xEFBE4786,
  5656. 0x0FC19DC6, 0x240CA1CC, 0x2DE92C6F, 0x4A7484AA, 0x5CB0A9DC, 0x76F988DA,
  5657. 0x983E5152, 0xA831C66D, 0xB00327C8, 0xBF597FC7, 0xC6E00BF3, 0xD5A79147,
  5658. 0x06CA6351, 0x14292967, 0x27B70A85, 0x2E1B2138, 0x4D2C6DFC, 0x53380D13,
  5659. 0x650A7354, 0x766A0ABB, 0x81C2C92E, 0x92722C85, 0xA2BFE8A1, 0xA81A664B,
  5660. 0xC24B8B70, 0xC76C51A3, 0xD192E819, 0xD6990624, 0xF40E3585, 0x106AA070,
  5661. 0x19A4C116, 0x1E376C08, 0x2748774C, 0x34B0BCB5, 0x391C0CB3, 0x4ED8AA4A,
  5662. 0x5B9CCA4F, 0x682E6FF3, 0x748F82EE, 0x78A5636F, 0x84C87814, 0x8CC70208,
  5663. 0x90BEFFFA, 0xA4506CEB, 0xBEF9A3F7, 0xC67178F2
  5664. };
  5665. static void Sha256Init(Sha256Ctx *Ctx)
  5666. {
  5667. Ctx->State[0] = 0x6A09E667;
  5668. Ctx->State[1] = 0xBB67AE85;
  5669. Ctx->State[2] = 0x3C6EF372;
  5670. Ctx->State[3] = 0xA54FF53A;
  5671. Ctx->State[4] = 0x510E527F;
  5672. Ctx->State[5] = 0x9B05688C;
  5673. Ctx->State[6] = 0x1F83D9AB;
  5674. Ctx->State[7] = 0x5BE0CD19;
  5675. Ctx->Len = 0;
  5676. }
  5677. static void Sha256ProcessBlock(Sha256Ctx *Ctx, BYTE *block)
  5678. {
  5679. unsigned int i;
  5680. DWORD w[64], temp1, temp2;
  5681. DWORD a = Ctx->State[0];
  5682. DWORD b = Ctx->State[1];
  5683. DWORD c = Ctx->State[2];
  5684. DWORD d = Ctx->State[3];
  5685. DWORD e = Ctx->State[4];
  5686. DWORD f = Ctx->State[5];
  5687. DWORD g = Ctx->State[6];
  5688. DWORD h = Ctx->State[7];
  5689. for (i = 0; i < 16; i++)
  5690. //w[ i ] = GET_UAA32BE(block, i);
  5691. w[i] = BE32(((DWORD*)block)[i]);
  5692. for (i = 16; i < 64; i++)
  5693. w[ i ] = SI4(w[ i - 2 ]) + w[ i - 7 ] + SI3(w[ i - 15 ]) + w[ i - 16 ];
  5694. for (i = 0; i < 64; i++)
  5695. {
  5696. temp1 = h + SI2(e) + F0(e, f, g) + k[ i ] + w[ i ];
  5697. temp2 = SI1(a) + F1(a, b, c);
  5698. h = g;
  5699. g = f;
  5700. f = e;
  5701. e = d + temp1;
  5702. d = c;
  5703. c = b;
  5704. b = a;
  5705. a = temp1 + temp2;
  5706. }
  5707. Ctx->State[0] += a;
  5708. Ctx->State[1] += b;
  5709. Ctx->State[2] += c;
  5710. Ctx->State[3] += d;
  5711. Ctx->State[4] += e;
  5712. Ctx->State[5] += f;
  5713. Ctx->State[6] += g;
  5714. Ctx->State[7] += h;
  5715. }
  5716. static void Sha256Update(Sha256Ctx *Ctx, BYTE *data, size_t len)
  5717. {
  5718. unsigned int b_len = Ctx->Len & 63,
  5719. r_len = (b_len ^ 63) + 1;
  5720. Ctx->Len += len;
  5721. if ( len < r_len )
  5722. {
  5723. memcpy(Ctx->Buffer + b_len, data, len);
  5724. return;
  5725. }
  5726. if ( r_len < 64 )
  5727. {
  5728. memcpy(Ctx->Buffer + b_len, data, r_len);
  5729. len -= r_len;
  5730. data += r_len;
  5731. Sha256ProcessBlock(Ctx, Ctx->Buffer);
  5732. }
  5733. for (; len >= 64; len -= 64, data += 64)
  5734. Sha256ProcessBlock(Ctx, data);
  5735. if ( len ) memcpy(Ctx->Buffer, data, len);
  5736. }
  5737. static void Sha256Finish(Sha256Ctx *Ctx, BYTE *hash)
  5738. {
  5739. unsigned int i, b_len = Ctx->Len & 63;
  5740. Ctx->Buffer[ b_len ] = 0x80;
  5741. if ( b_len ^ 63 ) memset(Ctx->Buffer + b_len + 1, 0, b_len ^ 63);
  5742. if ( b_len >= 56 )
  5743. {
  5744. Sha256ProcessBlock(Ctx, Ctx->Buffer);
  5745. memset(Ctx->Buffer, 0, 56);
  5746. }
  5747. //PUT_UAA64BE(Ctx->Buffer, (unsigned long long)(Ctx->Len * 8), 7);
  5748. ((uint64_t*)Ctx->Buffer)[7] = BE64((uint64_t)Ctx->Len << 3);
  5749. Sha256ProcessBlock(Ctx, Ctx->Buffer);
  5750. for (i = 0; i < 8; i++)
  5751. //PUT_UAA32BE(hash, Ctx->State[i], i);
  5752. ((DWORD*)hash)[i] = BE32(Ctx->State[i]);
  5753. }
  5754. void Sha256(BYTE *data, size_t len, BYTE *hash)
  5755. {
  5756. Sha256Ctx Ctx;
  5757. Sha256Init(&Ctx);
  5758. Sha256Update(&Ctx, data, len);
  5759. Sha256Finish(&Ctx, hash);
  5760. }
  5761. static void _Sha256HmacInit(Sha256HmacCtx *Ctx, BYTE *key, size_t klen)
  5762. {
  5763. BYTE IPad[64];
  5764. unsigned int i;
  5765. memset(IPad, 0x36, sizeof(IPad));
  5766. memset(Ctx->OPad, 0x5C, sizeof(Ctx->OPad));
  5767. if ( klen > 64 )
  5768. {
  5769. BYTE *temp = (BYTE*)alloca(32);
  5770. Sha256(key, klen, temp);
  5771. klen = 32;
  5772. key = temp;
  5773. }
  5774. for (i = 0; i < klen; i++)
  5775. {
  5776. IPad[ i ] ^= key[ i ];
  5777. Ctx->OPad[ i ] ^= key[ i ];
  5778. }
  5779. Sha256Init(&Ctx->ShaCtx);
  5780. Sha256Update(&Ctx->ShaCtx, IPad, sizeof(IPad));
  5781. }
  5782. static void _Sha256HmacUpdate(Sha256HmacCtx *Ctx, BYTE *data, size_t len)
  5783. {
  5784. Sha256Update(&Ctx->ShaCtx, data, len);
  5785. }
  5786. static void _Sha256HmacFinish(Sha256HmacCtx *Ctx, BYTE *hmac)
  5787. {
  5788. BYTE temp[32];
  5789. Sha256Finish(&Ctx->ShaCtx, temp);
  5790. Sha256Init(&Ctx->ShaCtx);
  5791. Sha256Update(&Ctx->ShaCtx, Ctx->OPad, sizeof(Ctx->OPad));
  5792. Sha256Update(&Ctx->ShaCtx, temp, sizeof(temp));
  5793. Sha256Finish(&Ctx->ShaCtx, hmac);
  5794. }
  5795. int_fast8_t Sha256Hmac(BYTE* key, BYTE* restrict data, DWORD len, BYTE* restrict hmac)
  5796. {
  5797. Sha256HmacCtx Ctx;
  5798. _Sha256HmacInit(&Ctx, key, 16);
  5799. _Sha256HmacUpdate(&Ctx, data, len);
  5800. _Sha256HmacFinish(&Ctx, hmac);
  5801. return TRUE;
  5802. }
  5803. #endif // No external Crypto
  5804. /*
  5805. * dns_srv.c
  5806. *
  5807. * This file contains the code for KMS SRV record lookup in DNS (_vlmcs._tcp.example.com IN SRV 0 0 1688 mykms.example.com)
  5808. *
  5809. */
  5810. #ifndef CONFIG
  5811. #define CONFIG "config.h"
  5812. #endif // CONFIG
  5813. #include CONFIG
  5814. #ifndef NO_DNS
  5815. #include "dns_srv.h"
  5816. #include <string.h>
  5817. #include <stdio.h>
  5818. #ifndef _WIN32
  5819. #include <signal.h>
  5820. #include <unistd.h>
  5821. #include <fcntl.h>
  5822. #include <errno.h>
  5823. #include <netdb.h>
  5824. //#ifndef DNS_PARSER_INTERNAL
  5825. #if __ANDROID__
  5826. #include <netinet/in.h>
  5827. #include "nameser.h"
  5828. #include "resolv.h"
  5829. #else // other Unix non-Android
  5830. #include <netinet/in.h>
  5831. #include <arpa/nameser.h>
  5832. #include <resolv.h>
  5833. #endif // other Unix non-Android
  5834. //#endif // DNS_PARSER_INTERNAL
  5835. #else // WIN32
  5836. #include <windns.h>
  5837. #endif // WIN32
  5838. #include "helpers.h"
  5839. #include "output.h"
  5840. #include "endian.h"
  5841. #if defined(DNS_PARSER_INTERNAL) && !defined(_WIN32)
  5842. #include "ns_name.h"
  5843. #include "ns_parse.h"
  5844. // Define macros to redirect DNS parser functions to internal versions
  5845. #undef ns_msg
  5846. #undef ns_initparse
  5847. #undef ns_parserr
  5848. #undef ns_rr
  5849. #undef ns_name_uncompress
  5850. #undef ns_msg_base
  5851. #undef ns_msg_end
  5852. #undef ns_rr_rdata
  5853. #undef ns_rr_type
  5854. #undef ns_msg_count
  5855. #undef ns_rr_class
  5856. #undef ns_s_an
  5857. #define ns_msg ns_msg_vlmcsd
  5858. #define ns_initparse ns_initparse_vlmcsd
  5859. #define ns_parserr ns_parserr_vlmcsd
  5860. #define ns_rr ns_rr_vlmcsd
  5861. #define ns_name_uncompress ns_name_uncompress_vlmcsd
  5862. #define ns_msg_base ns_msg_base_vlmcsd
  5863. #define ns_msg_end ns_msg_end_vlmcsd
  5864. #define ns_rr_rdata ns_rr_rdata_vlmcsd
  5865. #define ns_rr_type ns_rr_type_vlmcsd
  5866. #define ns_msg_count ns_msg_count_vlmcsd
  5867. #define ns_rr_class ns_rr_class_vlmcsd
  5868. #define ns_s_an ns_s_an_vlmcsd
  5869. #ifndef NS_MAXLABEL
  5870. #define NS_MAXLABEL 63
  5871. #endif
  5872. #endif // defined(DNS_PARSER_INTERNAL) && !defined(_WIN32)
  5873. //TODO: maybe move to helpers.c
  5874. static unsigned int isqrt(unsigned int n)
  5875. {
  5876. unsigned int c = 0x8000;
  5877. unsigned int g = 0x8000;
  5878. for(;;)
  5879. {
  5880. if(g*g > n)
  5881. g ^= c;
  5882. c >>= 1;
  5883. if(c == 0) return g;
  5884. g |= c;
  5885. }
  5886. }
  5887. /*
  5888. * Compare function for qsort to sort SRV records by priority and weight
  5889. * random_weight must be product of weight from SRV record and square root of a random number
  5890. */
  5891. static int kmsServerListCompareFunc1(const void* a, const void* b)
  5892. {
  5893. if ( !a && !b) return 0;
  5894. if ( a && !b) return -1;
  5895. if ( !a && b) return 1;
  5896. int priority_order = (int)((*(kms_server_dns_ptr*)a)->priority) - ((int)(*(kms_server_dns_ptr*)b)->priority);
  5897. if (priority_order) return priority_order;
  5898. return (int)((*(kms_server_dns_ptr*)b)->random_weight) - ((int)(*(kms_server_dns_ptr*)a)->random_weight);
  5899. }
  5900. /* Sort resulting SRV records */
  5901. void sortSrvRecords(kms_server_dns_ptr* serverlist, const int answers)
  5902. {
  5903. int i;
  5904. for (i = 0; i < answers; i++)
  5905. {
  5906. serverlist[i]->random_weight = (rand32() % 256) * isqrt(serverlist[i]->weight * 1000);
  5907. }
  5908. qsort(serverlist, answers, sizeof(kms_server_dns_ptr), kmsServerListCompareFunc1);
  5909. }
  5910. #define RECEIVE_BUFFER_SIZE 2048
  5911. #ifndef _WIN32 // UNIX resolver
  5912. /*
  5913. * Retrieves a raw DNS answer (a buffer of what came over the net)
  5914. * Result must be parsed
  5915. */
  5916. static int getDnsRawAnswer(const char *restrict query, unsigned char** receive_buffer)
  5917. {
  5918. if (res_init() < 0)
  5919. {
  5920. errorout("Cannot initialize resolver: %s", strerror(errno));
  5921. return 0;
  5922. }
  5923. //if(!(*receive_buffer = (unsigned char*)malloc(RECEIVE_BUFFER_SIZE))) OutOfMemory();
  5924. *receive_buffer = (unsigned char*)vlmcsd_malloc(RECEIVE_BUFFER_SIZE);
  5925. int bytes_received;
  5926. if (*query == '.')
  5927. {
  5928. # if __ANDROID__ || __GLIBC__ /* including __UCLIBC__*/ || __APPLE__ || __CYGWIN__ || __FreeBSD__ || __NetBSD__ || __DragonFly__ || __OpenBSD__ || __sun__
  5929. bytes_received = res_querydomain("_vlmcs._tcp", query + 1, ns_c_in, ns_t_srv, *receive_buffer, RECEIVE_BUFFER_SIZE);
  5930. # else
  5931. char* querystring = (char*)alloca(strlen(query) + 12);
  5932. strcpy(querystring, "_vlmcs._tcp");
  5933. strcat(querystring, query);
  5934. bytes_received = res_query(querystring, ns_c_in, ns_t_srv, *receive_buffer, RECEIVE_BUFFER_SIZE);
  5935. # endif
  5936. }
  5937. else
  5938. {
  5939. bytes_received = res_search("_vlmcs._tcp", ns_c_in, ns_t_srv, *receive_buffer, RECEIVE_BUFFER_SIZE);
  5940. }
  5941. if (bytes_received < 0)
  5942. {
  5943. errorout("Fatal: DNS query to %s%s failed: %s\n", "_vlmcs._tcp", *query == '.' ? query : "", hstrerror(h_errno));
  5944. return 0;
  5945. }
  5946. return bytes_received;
  5947. }
  5948. /*
  5949. * Retrieves an unsorted array of SRV records (Unix / Posix)
  5950. */
  5951. int getKmsServerList(kms_server_dns_ptr** serverlist, const char *restrict query)
  5952. {
  5953. unsigned char* receive_buffer;
  5954. *serverlist = NULL;
  5955. int bytes_received = getDnsRawAnswer(query, &receive_buffer);
  5956. if (bytes_received == 0) return 0;
  5957. ns_msg msg;
  5958. if (ns_initparse(receive_buffer, bytes_received, &msg) < 0)
  5959. {
  5960. errorout("Fatal: Incorrect DNS response: %s\n", strerror(errno));
  5961. free(receive_buffer);
  5962. return 0;
  5963. }
  5964. uint16_t i, answers = ns_msg_count(msg, ns_s_an);
  5965. //if(!(*serverlist = (kms_server_dns_ptr*)malloc(answers * sizeof(kms_server_dns_ptr)))) OutOfMemory();
  5966. *serverlist = (kms_server_dns_ptr*)malloc(answers * sizeof(kms_server_dns_ptr));
  5967. memset(*serverlist, 0, answers * sizeof(kms_server_dns_ptr));
  5968. for (i = 0; i < answers; i++)
  5969. {
  5970. ns_rr rr;
  5971. if (ns_parserr(&msg, ns_s_an, i, &rr) < 0)
  5972. {
  5973. errorout("Warning: Error in DNS resource record: %s\n", strerror(errno));
  5974. continue;
  5975. }
  5976. if (ns_rr_type(rr) != ns_t_srv)
  5977. {
  5978. errorout("Warning: DNS server returned non-SRV record\n");
  5979. continue;
  5980. }
  5981. if (ns_rr_class(rr) != ns_c_in)
  5982. {
  5983. errorout("Warning: DNS server returned non-IN class record\n");
  5984. continue;
  5985. }
  5986. dns_srv_record_ptr srvrecord = (dns_srv_record_ptr)ns_rr_rdata(rr);
  5987. kms_server_dns_ptr kms_server = (kms_server_dns_ptr)vlmcsd_malloc(sizeof(kms_server_dns_t));
  5988. (*serverlist)[i] = kms_server;
  5989. if (ns_name_uncompress(ns_msg_base(msg), ns_msg_end(msg), srvrecord->name, kms_server->serverName, sizeof(kms_server->serverName)) < 0)
  5990. {
  5991. errorout("Warning: No valid DNS name returned in SRV record: %s\n", strerror(errno));
  5992. continue;
  5993. }
  5994. sprintf(kms_server->serverName + strlen(kms_server->serverName), ":%hu", GET_UA16BE(&srvrecord->port));
  5995. kms_server->priority = GET_UA16BE(&srvrecord->priority);
  5996. kms_server->weight = GET_UA16BE(&srvrecord->weight);
  5997. }
  5998. free(receive_buffer);
  5999. return answers;
  6000. }
  6001. #else // WIN32 (Windows Resolver)
  6002. /*
  6003. * Retrieves an unsorted array of SRV records (Windows)
  6004. */
  6005. int getKmsServerList(kms_server_dns_ptr** serverlist, const char *const restrict query)
  6006. {
  6007. # define MAX_DNS_NAME_SIZE 254
  6008. *serverlist = NULL;
  6009. PDNS_RECORD receive_buffer;
  6010. char dnsDomain[MAX_DNS_NAME_SIZE];
  6011. char FqdnQuery[MAX_DNS_NAME_SIZE];
  6012. DWORD size = MAX_DNS_NAME_SIZE;
  6013. DNS_STATUS result;
  6014. int answers = 0;
  6015. PDNS_RECORD dns_iterator;
  6016. if (*query == '-')
  6017. {
  6018. if (!GetComputerNameExA(ComputerNamePhysicalDnsDomain, dnsDomain, &size))
  6019. {
  6020. errorout("Fatal: Could not determine computer's DNS name: %s\n", vlmcsd_strerror(GetLastError()));
  6021. return 0;
  6022. }
  6023. strcpy(FqdnQuery, "_vlmcs._tcp.");
  6024. strncat(FqdnQuery, dnsDomain, MAX_DNS_NAME_SIZE - 12);
  6025. }
  6026. else
  6027. {
  6028. strcpy(FqdnQuery, "_vlmcs._tcp");
  6029. strncat(FqdnQuery, query, MAX_DNS_NAME_SIZE - 11);
  6030. }
  6031. if ((result = DnsQuery_UTF8(FqdnQuery, DNS_TYPE_SRV, 0, NULL, &receive_buffer, NULL)) != 0)
  6032. {
  6033. errorout("Fatal: DNS query to %s failed: %s\n", FqdnQuery, vlmcsd_strerror(result));
  6034. return 0;
  6035. }
  6036. for (dns_iterator = receive_buffer; dns_iterator; dns_iterator = dns_iterator->pNext)
  6037. {
  6038. if (dns_iterator->Flags.S.Section != 1) continue;
  6039. if (dns_iterator->wType != DNS_TYPE_SRV)
  6040. {
  6041. errorout("Warning: DNS server returned non-SRV record\n");
  6042. continue;
  6043. }
  6044. answers++;
  6045. }
  6046. *serverlist = (kms_server_dns_ptr*)vlmcsd_malloc(answers * sizeof(kms_server_dns_ptr));
  6047. for (answers = 0, dns_iterator = receive_buffer; dns_iterator; dns_iterator = dns_iterator->pNext)
  6048. {
  6049. if (dns_iterator->wType != DNS_TYPE_SRV) continue;
  6050. kms_server_dns_ptr kms_server = (kms_server_dns_ptr)vlmcsd_malloc(sizeof(kms_server_dns_t));
  6051. memset(kms_server, 0, sizeof(kms_server_dns_t));
  6052. snprintf(kms_server->serverName, sizeof(kms_server->serverName), "%s:%hu", dns_iterator->Data.SRV.pNameTarget, dns_iterator->Data.SRV.wPort);
  6053. kms_server->priority = dns_iterator->Data.SRV.wPriority;
  6054. kms_server->weight = dns_iterator->Data.SRV.wWeight;
  6055. (*serverlist)[answers++] = kms_server;
  6056. }
  6057. //sortSrvRecords(*serverlist, answers, NoSrvRecordPriority);
  6058. DnsRecordListFree(receive_buffer, DnsFreeRecordList);
  6059. return answers;
  6060. # undef MAX_DNS_NAME_SIZE
  6061. }
  6062. #endif // _WIN32
  6063. #undef RECEIVE_BUFFER_SIZE
  6064. #endif // NO_DNS
  6065. /*
  6066. * Copyright (c) 1996,1999 by Internet Software Consortium.
  6067. *
  6068. * Permission to use, copy, modify, and distribute this software for any
  6069. * purpose with or without fee is hereby granted, provided that the above
  6070. * copyright notice and this permission notice appear in all copies.
  6071. *
  6072. * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS
  6073. * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
  6074. * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE
  6075. * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
  6076. * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
  6077. * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
  6078. * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
  6079. * SOFTWARE.
  6080. */
  6081. /*
  6082. * Modified by Hotbird64 for use with vlmcs.
  6083. */
  6084. #ifndef CONFIG
  6085. #define CONFIG "config.h"
  6086. #endif // CONFIG
  6087. #include CONFIG
  6088. #ifdef DNS_PARSER_INTERNAL
  6089. #ifndef NO_DNS
  6090. /* Import. */
  6091. #include <sys/types.h>
  6092. #include <errno.h>
  6093. #include <string.h>
  6094. #include "types.h"
  6095. #include "endian.h"
  6096. #include "ns_name.h"
  6097. #include "ns_parse.h"
  6098. /* Macros. */
  6099. #define NS_GET16_VLMCSD(s, cp) do { \
  6100. (s) = GET_UA16BE(cp); \
  6101. (cp) += NS_INT16SZ; \
  6102. } while (0)
  6103. #define NS_GET32_VLMCSD(l, cp) do { \
  6104. (l) = GET_UA32BE(cp); \
  6105. (cp) += NS_INT32SZ; \
  6106. } while (0)
  6107. #define RETERR(err) do { errno = (err); return (-1); } while (0)
  6108. /* Forward. */
  6109. static void setsection_vlmcsd(ns_msg_vlmcsd *msg, ns_sect_vlmcsd sect);
  6110. static int dn_skipname_vlmcsd(const unsigned char *s, const unsigned char *end)
  6111. {
  6112. const unsigned char *p;
  6113. for (p=s; p<end; p++)
  6114. if (!*p) return p-s+1;
  6115. else if (*p>=192)
  6116. {if (p+1<end) return p-s+2;
  6117. else break;}
  6118. return -1;
  6119. }
  6120. static int
  6121. ns_skiprr_vlmcsd(const uint8_t *ptr, const uint8_t *eom, ns_sect_vlmcsd section, int count) {
  6122. const uint8_t *optr = ptr;
  6123. for ((void)NULL; count > 0; count--) {
  6124. int b, rdlength;
  6125. b = dn_skipname_vlmcsd(ptr, eom);
  6126. if (b < 0)
  6127. RETERR(EMSGSIZE);
  6128. ptr += b/*Name*/ + NS_INT16SZ/*Type*/ + NS_INT16SZ/*Class*/;
  6129. if (section != ns_s_qd_vlmcsd) {
  6130. if (ptr + NS_INT32SZ + NS_INT16SZ > eom)
  6131. RETERR(EMSGSIZE);
  6132. ptr += NS_INT32SZ/*TTL*/;
  6133. NS_GET16_VLMCSD(rdlength, ptr);
  6134. ptr += rdlength/*RData*/;
  6135. }
  6136. }
  6137. if (ptr > eom)
  6138. RETERR(EMSGSIZE);
  6139. return (ptr - optr);
  6140. }
  6141. int
  6142. ns_initparse_vlmcsd(const uint8_t *msg, int msglen, ns_msg_vlmcsd *handle) {
  6143. const uint8_t *eom = msg + msglen;
  6144. int i;
  6145. memset(handle, 0x5e, sizeof *handle);
  6146. handle->_msg = msg;
  6147. handle->_eom = eom;
  6148. if (msg + NS_INT16SZ > eom)
  6149. RETERR(EMSGSIZE);
  6150. NS_GET16_VLMCSD(handle->_id, msg);
  6151. if (msg + NS_INT16SZ > eom)
  6152. RETERR(EMSGSIZE);
  6153. NS_GET16_VLMCSD(handle->_flags, msg);
  6154. for (i = 0; i < ns_s_max_vlmcsd; i++) {
  6155. if (msg + NS_INT16SZ > eom)
  6156. RETERR(EMSGSIZE);
  6157. NS_GET16_VLMCSD(handle->_counts[i], msg);
  6158. }
  6159. for (i = 0; i < ns_s_max_vlmcsd; i++)
  6160. if (handle->_counts[i] == 0)
  6161. handle->_sections[i] = NULL;
  6162. else {
  6163. int b = ns_skiprr_vlmcsd(msg, eom, (ns_sect_vlmcsd)i,
  6164. handle->_counts[i]);
  6165. if (b < 0)
  6166. return (-1);
  6167. handle->_sections[i] = msg;
  6168. msg += b;
  6169. }
  6170. if (msg > eom)
  6171. RETERR(EMSGSIZE);
  6172. handle->_eom = msg;
  6173. setsection_vlmcsd(handle, ns_s_max_vlmcsd);
  6174. return (0);
  6175. }
  6176. int
  6177. ns_parserr_vlmcsd(ns_msg_vlmcsd *handle, ns_sect_vlmcsd section, int rrnum, ns_rr_vlmcsd *rr) {
  6178. int b;
  6179. /* Make section right. */
  6180. if (section >= ns_s_max_vlmcsd)
  6181. RETERR(ENODEV);
  6182. if (section != handle->_sect)
  6183. setsection_vlmcsd(handle, section);
  6184. /* Make rrnum right. */
  6185. if (rrnum == -1)
  6186. rrnum = handle->_rrnum;
  6187. if (rrnum < 0 || rrnum >= handle->_counts[(int)section])
  6188. RETERR(ENODEV);
  6189. if (rrnum < handle->_rrnum)
  6190. setsection_vlmcsd(handle, section);
  6191. if (rrnum > handle->_rrnum) {
  6192. b = ns_skiprr_vlmcsd(handle->_msg_ptr, handle->_eom, section,
  6193. rrnum - handle->_rrnum);
  6194. if (b < 0)
  6195. return (-1);
  6196. handle->_msg_ptr += b;
  6197. handle->_rrnum = rrnum;
  6198. }
  6199. /* Do the parse. */
  6200. b = ns_name_uncompress_vlmcsd(handle->_msg, handle->_eom,
  6201. handle->_msg_ptr, rr->name, NS_MAXDNAME);
  6202. if (b < 0)
  6203. return (-1);
  6204. handle->_msg_ptr += b;
  6205. if (handle->_msg_ptr + NS_INT16SZ + NS_INT16SZ > handle->_eom)
  6206. RETERR(EMSGSIZE);
  6207. NS_GET16_VLMCSD(rr->type, handle->_msg_ptr);
  6208. NS_GET16_VLMCSD(rr->rr_class, handle->_msg_ptr);
  6209. if (section == ns_s_qd_vlmcsd) {
  6210. rr->ttl = 0;
  6211. rr->rdlength = 0;
  6212. rr->rdata = NULL;
  6213. } else {
  6214. if (handle->_msg_ptr + NS_INT32SZ + NS_INT16SZ > handle->_eom)
  6215. RETERR(EMSGSIZE);
  6216. NS_GET32_VLMCSD(rr->ttl, handle->_msg_ptr);
  6217. NS_GET16_VLMCSD(rr->rdlength, handle->_msg_ptr);
  6218. if (handle->_msg_ptr + rr->rdlength > handle->_eom)
  6219. RETERR(EMSGSIZE);
  6220. rr->rdata = handle->_msg_ptr;
  6221. handle->_msg_ptr += rr->rdlength;
  6222. }
  6223. if (++handle->_rrnum > handle->_counts[(int)section])
  6224. setsection_vlmcsd(handle, (ns_sect_vlmcsd)((int)section + 1));
  6225. /* All done. */
  6226. return (0);
  6227. }
  6228. /* Private. */
  6229. static void
  6230. setsection_vlmcsd(ns_msg_vlmcsd *msg, ns_sect_vlmcsd sect) {
  6231. msg->_sect = sect;
  6232. if (sect == ns_s_max_vlmcsd) {
  6233. msg->_rrnum = -1;
  6234. msg->_msg_ptr = NULL;
  6235. } else {
  6236. msg->_rrnum = 0;
  6237. msg->_msg_ptr = msg->_sections[(int)sect];
  6238. }
  6239. }
  6240. #endif // !NO_DNS
  6241. #endif // DNS_PARSER_INTERNAL
  6242. /*
  6243. * Copyright (c) 1996,1999 by Internet Software Consortium.
  6244. *
  6245. * Permission to use, copy, modify, and distribute this software for any
  6246. * purpose with or without fee is hereby granted, provided that the above
  6247. * copyright notice and this permission notice appear in all copies.
  6248. *
  6249. * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS
  6250. * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
  6251. * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE
  6252. * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
  6253. * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
  6254. * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
  6255. * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
  6256. * SOFTWARE.
  6257. */
  6258. /*
  6259. * Modified by Hotbird64 for use with vlmcs.
  6260. */
  6261. #ifndef CONFIG
  6262. #define CONFIG "config.h"
  6263. #endif // CONFIG
  6264. #include CONFIG
  6265. #ifdef DNS_PARSER_INTERNAL
  6266. #ifndef NO_DNS
  6267. #include <sys/types.h>
  6268. #include <errno.h>
  6269. #include <string.h>
  6270. #include <ctype.h>
  6271. #include <stdlib.h>
  6272. #include <stdio.h>
  6273. #include <limits.h>
  6274. #include "types.h"
  6275. #include "ns_name.h"
  6276. #ifdef SPRINTF_CHAR
  6277. # define SPRINTF(x) strlen(sprintf/**/x)
  6278. #else
  6279. # define SPRINTF(x) ((size_t)sprintf x)
  6280. #endif
  6281. #define NS_TYPE_ELT 0x40 /* EDNS0 extended label type */
  6282. #define DNS_LABELTYPE_BITSTRING 0x41
  6283. #define NS_MAXCDNAME 255
  6284. #define NS_CMPRSFLGS 0xc0
  6285. /* Data. */
  6286. static char digits[] = "0123456789";
  6287. /* Forward. */
  6288. static int special_vlmcsd(int);
  6289. static int printable_vlmcsd(int);
  6290. static int labellen_vlmcsd(const uint8_t *);
  6291. static int decode_bitstring_vlmcsd(const char **, char *, const char *);
  6292. /*
  6293. * ns_name_ntop(src, dst, dstsiz)
  6294. * Convert an encoded domain name to printable ascii as per RFC1035.
  6295. * return:
  6296. * Number of bytes written to buffer, or -1 (with errno set)
  6297. * notes:
  6298. * The root is returned as "."
  6299. * All other domains are returned in non absolute form
  6300. */
  6301. static int
  6302. ns_name_ntop_vlmcsd(const uint8_t *src, char *dst, size_t dstsiz)
  6303. {
  6304. const uint8_t *cp;
  6305. char *dn, *eom;
  6306. uint8_t c;
  6307. uint32_t n;
  6308. int l;
  6309. cp = src;
  6310. dn = dst;
  6311. eom = dst + dstsiz;
  6312. while ((n = *cp++) != 0) {
  6313. if ((n & NS_CMPRSFLGS) == NS_CMPRSFLGS) {
  6314. /* Some kind of compression pointer. */
  6315. errno = EMSGSIZE;
  6316. return (-1);
  6317. }
  6318. if (dn != dst) {
  6319. if (dn >= eom) {
  6320. errno = EMSGSIZE;
  6321. return (-1);
  6322. }
  6323. *dn++ = '.';
  6324. }
  6325. if ((l = labellen_vlmcsd(cp - 1)) < 0) {
  6326. errno = EMSGSIZE; /* XXX */
  6327. return(-1);
  6328. }
  6329. if (dn + l >= eom) {
  6330. errno = EMSGSIZE;
  6331. return (-1);
  6332. }
  6333. if ((n & NS_CMPRSFLGS) == NS_TYPE_ELT) {
  6334. int m;
  6335. if (n != DNS_LABELTYPE_BITSTRING) {
  6336. /* XXX: labellen should reject this case */
  6337. errno = EINVAL;
  6338. return(-1);
  6339. }
  6340. if ((m = decode_bitstring_vlmcsd((const char **)&cp, dn, eom)) < 0)
  6341. {
  6342. errno = EMSGSIZE;
  6343. return(-1);
  6344. }
  6345. dn += m;
  6346. continue;
  6347. }
  6348. for ((void)NULL; l > 0; l--) {
  6349. c = *cp++;
  6350. if (special_vlmcsd(c)) {
  6351. if (dn + 1 >= eom) {
  6352. errno = EMSGSIZE;
  6353. return (-1);
  6354. }
  6355. *dn++ = '\\';
  6356. *dn++ = (char)c;
  6357. } else if (!printable_vlmcsd(c)) {
  6358. if (dn + 3 >= eom) {
  6359. errno = EMSGSIZE;
  6360. return (-1);
  6361. }
  6362. *dn++ = '\\';
  6363. *dn++ = digits[c / 100];
  6364. *dn++ = digits[(c % 100) / 10];
  6365. *dn++ = digits[c % 10];
  6366. } else {
  6367. if (dn >= eom) {
  6368. errno = EMSGSIZE;
  6369. return (-1);
  6370. }
  6371. *dn++ = (char)c;
  6372. }
  6373. }
  6374. }
  6375. if (dn == dst) {
  6376. if (dn >= eom) {
  6377. errno = EMSGSIZE;
  6378. return (-1);
  6379. }
  6380. *dn++ = '.';
  6381. }
  6382. if (dn >= eom) {
  6383. errno = EMSGSIZE;
  6384. return (-1);
  6385. }
  6386. *dn++ = '\0';
  6387. return (dn - dst);
  6388. }
  6389. static int
  6390. ns_name_unpack_vlmcsd(const uint8_t *msg, const uint8_t *eom, const uint8_t *src,
  6391. uint8_t *dst, size_t dstsiz)
  6392. {
  6393. const uint8_t *srcp, *dstlim;
  6394. uint8_t *dstp;
  6395. int n, len, checked, l;
  6396. len = -1;
  6397. checked = 0;
  6398. dstp = dst;
  6399. srcp = src;
  6400. dstlim = dst + dstsiz;
  6401. if (srcp < msg || srcp >= eom) {
  6402. errno = EMSGSIZE;
  6403. return (-1);
  6404. }
  6405. /* Fetch next label in domain name. */
  6406. while ((n = *srcp++) != 0) {
  6407. /* Check for indirection. */
  6408. switch (n & NS_CMPRSFLGS) {
  6409. case 0:
  6410. case NS_TYPE_ELT:
  6411. /* Limit checks. */
  6412. if ((l = labellen_vlmcsd(srcp - 1)) < 0) {
  6413. errno = EMSGSIZE;
  6414. return(-1);
  6415. }
  6416. if (dstp + l + 1 >= dstlim || srcp + l >= eom) {
  6417. errno = EMSGSIZE;
  6418. return (-1);
  6419. }
  6420. checked += l + 1;
  6421. *dstp++ = n;
  6422. memcpy(dstp, srcp, l);
  6423. dstp += l;
  6424. srcp += l;
  6425. break;
  6426. case NS_CMPRSFLGS:
  6427. if (srcp >= eom) {
  6428. errno = EMSGSIZE;
  6429. return (-1);
  6430. }
  6431. if (len < 0)
  6432. len = srcp - src + 1;
  6433. srcp = msg + (((n & 0x3f) << 8) | (*srcp & 0xff));
  6434. if (srcp < msg || srcp >= eom) { /* Out of range. */
  6435. errno = EMSGSIZE;
  6436. return (-1);
  6437. }
  6438. checked += 2;
  6439. /*
  6440. * Check for loops in the compressed name;
  6441. * if we've looked at the whole message,
  6442. * there must be a loop.
  6443. */
  6444. if (checked >= eom - msg) {
  6445. errno = EMSGSIZE;
  6446. return (-1);
  6447. }
  6448. break;
  6449. default:
  6450. errno = EMSGSIZE;
  6451. return (-1); /* flag error */
  6452. }
  6453. }
  6454. *dstp = '\0';
  6455. if (len < 0)
  6456. len = srcp - src;
  6457. return (len);
  6458. }
  6459. /*
  6460. * ns_name_uncompress_vlmcsd(msg, eom, src, dst, dstsiz)
  6461. * Expand compressed domain name to presentation format.
  6462. * return:
  6463. * Number of bytes read out of `src', or -1 (with errno set).
  6464. * note:
  6465. * Root domain returns as "." not "".
  6466. */
  6467. int
  6468. ns_name_uncompress_vlmcsd(const uint8_t *msg, const uint8_t *eom, const uint8_t *src,
  6469. char *dst, size_t dstsiz)
  6470. {
  6471. uint8_t tmp[NS_MAXCDNAME];
  6472. int n;
  6473. if ((n = ns_name_unpack_vlmcsd(msg, eom, src, tmp, sizeof tmp)) == -1)
  6474. return (-1);
  6475. if (ns_name_ntop_vlmcsd(tmp, dst, dstsiz) == -1)
  6476. return (-1);
  6477. return (n);
  6478. }
  6479. /*
  6480. * special(ch)
  6481. * Thinking in noninternationalized USASCII (per the DNS spec),
  6482. * is this characted special ("in need of quoting") ?
  6483. * return:
  6484. * boolean.
  6485. */
  6486. static int
  6487. special_vlmcsd(int ch) {
  6488. switch (ch) {
  6489. case 0x22: /* '"' */
  6490. case 0x2E: /* '.' */
  6491. case 0x3B: /* ';' */
  6492. case 0x5C: /* '\\' */
  6493. case 0x28: /* '(' */
  6494. case 0x29: /* ')' */
  6495. /* Special modifiers in zone files. */
  6496. case 0x40: /* '@' */
  6497. case 0x24: /* '$' */
  6498. return (1);
  6499. default:
  6500. return (0);
  6501. }
  6502. }
  6503. /*
  6504. * printable(ch)
  6505. * Thinking in noninternationalized USASCII (per the DNS spec),
  6506. * is this character visible and not a space when printed ?
  6507. * return:
  6508. * boolean.
  6509. */
  6510. static int
  6511. printable_vlmcsd(int ch) {
  6512. return (ch > 0x20 && ch < 0x7f);
  6513. }
  6514. static int
  6515. decode_bitstring_vlmcsd(const char **cpp, char *dn, const char *eom)
  6516. {
  6517. const char *cp = *cpp;
  6518. char *beg = dn, tc;
  6519. int b, blen, plen;
  6520. if ((blen = (*cp & 0xff)) == 0)
  6521. blen = 256;
  6522. plen = (blen + 3) / 4;
  6523. plen += sizeof("\\[x/]") + (blen > 99 ? 3 : (blen > 9) ? 2 : 1);
  6524. if (dn + plen >= eom)
  6525. return(-1);
  6526. cp++;
  6527. dn += SPRINTF((dn, "\\[x"));
  6528. for (b = blen; b > 7; b -= 8, cp++)
  6529. dn += SPRINTF((dn, "%02x", *cp & 0xff));
  6530. if (b > 4) {
  6531. tc = *cp++;
  6532. dn += SPRINTF((dn, "%02x", tc & (0xff << (8 - b))));
  6533. } else if (b > 0) {
  6534. tc = *cp++;
  6535. dn += SPRINTF((dn, "%1x",
  6536. ((tc >> 4) & 0x0f) & (0x0f << (4 - b))));
  6537. }
  6538. dn += SPRINTF((dn, "/%d]", blen));
  6539. *cpp = cp;
  6540. return(dn - beg);
  6541. }
  6542. static int
  6543. labellen_vlmcsd(const uint8_t *lp)
  6544. {
  6545. int bitlen;
  6546. uint8_t l = *lp;
  6547. if ((l & NS_CMPRSFLGS) == NS_CMPRSFLGS) {
  6548. /* should be avoided by the caller */
  6549. return(-1);
  6550. }
  6551. if ((l & NS_CMPRSFLGS) == NS_TYPE_ELT) {
  6552. if (l == DNS_LABELTYPE_BITSTRING) {
  6553. if ((bitlen = *(lp + 1)) == 0)
  6554. bitlen = 256;
  6555. return((bitlen + 7 ) / 8 + 1);
  6556. }
  6557. return(-1); /* unknwon ELT */
  6558. }
  6559. return(l);
  6560. }
  6561. #endif // !NO_DNS
  6562. #endif // DNS_PARSER_INTERNAL