ckuath.c 400 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795279627972798279928002801280228032804280528062807280828092810281128122813281428152816281728182819282028212822282328242825282628272828282928302831283228332834283528362837283828392840284128422843284428452846284728482849285028512852285328542855285628572858285928602861286228632864286528662867286828692870287128722873287428752876287728782879288028812882288328842885288628872888288928902891289228932894289528962897289828992900290129022903290429052906290729082909291029112912291329142915291629172918291929202921292229232924292529262927292829292930293129322933293429352936293729382939294029412942294329442945294629472948294929502951295229532954295529562957295829592960296129622963296429652966296729682969297029712972297329742975297629772978297929802981298229832984298529862987298829892990299129922993299429952996299729982999300030013002300330043005300630073008300930103011301230133014301530163017301830193020302130223023302430253026302730283029303030313032303330343035303630373038303930403041304230433044304530463047304830493050305130523053305430553056305730583059306030613062306330643065306630673068306930703071307230733074307530763077307830793080308130823083308430853086308730883089309030913092309330943095309630973098309931003101310231033104310531063107310831093110311131123113311431153116311731183119312031213122312331243125312631273128312931303131313231333134313531363137313831393140314131423143314431453146314731483149315031513152315331543155315631573158315931603161316231633164316531663167316831693170317131723173317431753176317731783179318031813182318331843185318631873188318931903191319231933194319531963197319831993200320132023203320432053206320732083209321032113212321332143215321632173218321932203221322232233224322532263227322832293230323132323233323432353236323732383239324032413242324332443245324632473248324932503251325232533254325532563257325832593260326132623263326432653266326732683269327032713272327332743275327632773278327932803281328232833284328532863287328832893290329132923293329432953296329732983299330033013302330333043305330633073308330933103311331233133314331533163317331833193320332133223323332433253326332733283329333033313332333333343335333633373338333933403341334233433344334533463347334833493350335133523353335433553356335733583359336033613362336333643365336633673368336933703371337233733374337533763377337833793380338133823383338433853386338733883389339033913392339333943395339633973398339934003401340234033404340534063407340834093410341134123413341434153416341734183419342034213422342334243425342634273428342934303431343234333434343534363437343834393440344134423443344434453446344734483449345034513452345334543455345634573458345934603461346234633464346534663467346834693470347134723473347434753476347734783479348034813482348334843485348634873488348934903491349234933494349534963497349834993500350135023503350435053506350735083509351035113512351335143515351635173518351935203521352235233524352535263527352835293530353135323533353435353536353735383539354035413542354335443545354635473548354935503551355235533554355535563557355835593560356135623563356435653566356735683569357035713572357335743575357635773578357935803581358235833584358535863587358835893590359135923593359435953596359735983599360036013602360336043605360636073608360936103611361236133614361536163617361836193620362136223623362436253626362736283629363036313632363336343635363636373638363936403641364236433644364536463647364836493650365136523653365436553656365736583659366036613662366336643665366636673668366936703671367236733674367536763677367836793680368136823683368436853686368736883689369036913692369336943695369636973698369937003701370237033704370537063707370837093710371137123713371437153716371737183719372037213722372337243725372637273728372937303731373237333734373537363737373837393740374137423743374437453746374737483749375037513752375337543755375637573758375937603761376237633764376537663767376837693770377137723773377437753776377737783779378037813782378337843785378637873788378937903791379237933794379537963797379837993800380138023803380438053806380738083809381038113812381338143815381638173818381938203821382238233824382538263827382838293830383138323833383438353836383738383839384038413842384338443845384638473848384938503851385238533854385538563857385838593860386138623863386438653866386738683869387038713872387338743875387638773878387938803881388238833884388538863887388838893890389138923893389438953896389738983899390039013902390339043905390639073908390939103911391239133914391539163917391839193920392139223923392439253926392739283929393039313932393339343935393639373938393939403941394239433944394539463947394839493950395139523953395439553956395739583959396039613962396339643965396639673968396939703971397239733974397539763977397839793980398139823983398439853986398739883989399039913992399339943995399639973998399940004001400240034004400540064007400840094010401140124013401440154016401740184019402040214022402340244025402640274028402940304031403240334034403540364037403840394040404140424043404440454046404740484049405040514052405340544055405640574058405940604061406240634064406540664067406840694070407140724073407440754076407740784079408040814082408340844085408640874088408940904091409240934094409540964097409840994100410141024103410441054106410741084109411041114112411341144115411641174118411941204121412241234124412541264127412841294130413141324133413441354136413741384139414041414142414341444145414641474148414941504151415241534154415541564157415841594160416141624163416441654166416741684169417041714172417341744175417641774178417941804181418241834184418541864187418841894190419141924193419441954196419741984199420042014202420342044205420642074208420942104211421242134214421542164217421842194220422142224223422442254226422742284229423042314232423342344235423642374238423942404241424242434244424542464247424842494250425142524253425442554256425742584259426042614262426342644265426642674268426942704271427242734274427542764277427842794280428142824283428442854286428742884289429042914292429342944295429642974298429943004301430243034304430543064307430843094310431143124313431443154316431743184319432043214322432343244325432643274328432943304331433243334334433543364337433843394340434143424343434443454346434743484349435043514352435343544355435643574358435943604361436243634364436543664367436843694370437143724373437443754376437743784379438043814382438343844385438643874388438943904391439243934394439543964397439843994400440144024403440444054406440744084409441044114412441344144415441644174418441944204421442244234424442544264427442844294430443144324433443444354436443744384439444044414442444344444445444644474448444944504451445244534454445544564457445844594460446144624463446444654466446744684469447044714472447344744475447644774478447944804481448244834484448544864487448844894490449144924493449444954496449744984499450045014502450345044505450645074508450945104511451245134514451545164517451845194520452145224523452445254526452745284529453045314532453345344535453645374538453945404541454245434544454545464547454845494550455145524553455445554556455745584559456045614562456345644565456645674568456945704571457245734574457545764577457845794580458145824583458445854586458745884589459045914592459345944595459645974598459946004601460246034604460546064607460846094610461146124613461446154616461746184619462046214622462346244625462646274628462946304631463246334634463546364637463846394640464146424643464446454646464746484649465046514652465346544655465646574658465946604661466246634664466546664667466846694670467146724673467446754676467746784679468046814682468346844685468646874688468946904691469246934694469546964697469846994700470147024703470447054706470747084709471047114712471347144715471647174718471947204721472247234724472547264727472847294730473147324733473447354736473747384739474047414742474347444745474647474748474947504751475247534754475547564757475847594760476147624763476447654766476747684769477047714772477347744775477647774778477947804781478247834784478547864787478847894790479147924793479447954796479747984799480048014802480348044805480648074808480948104811481248134814481548164817481848194820482148224823482448254826482748284829483048314832483348344835483648374838483948404841484248434844484548464847484848494850485148524853485448554856485748584859486048614862486348644865486648674868486948704871487248734874487548764877487848794880488148824883488448854886488748884889489048914892489348944895489648974898489949004901490249034904490549064907490849094910491149124913491449154916491749184919492049214922492349244925492649274928492949304931493249334934493549364937493849394940494149424943494449454946494749484949495049514952495349544955495649574958495949604961496249634964496549664967496849694970497149724973497449754976497749784979498049814982498349844985498649874988498949904991499249934994499549964997499849995000500150025003500450055006500750085009501050115012501350145015501650175018501950205021502250235024502550265027502850295030503150325033503450355036503750385039504050415042504350445045504650475048504950505051505250535054505550565057505850595060506150625063506450655066506750685069507050715072507350745075507650775078507950805081508250835084508550865087508850895090509150925093509450955096509750985099510051015102510351045105510651075108510951105111511251135114511551165117511851195120512151225123512451255126512751285129513051315132513351345135513651375138513951405141514251435144514551465147514851495150515151525153515451555156515751585159516051615162516351645165516651675168516951705171517251735174517551765177517851795180518151825183518451855186518751885189519051915192519351945195519651975198519952005201520252035204520552065207520852095210521152125213521452155216521752185219522052215222522352245225522652275228522952305231523252335234523552365237523852395240524152425243524452455246524752485249525052515252525352545255525652575258525952605261526252635264526552665267526852695270527152725273527452755276527752785279528052815282528352845285528652875288528952905291529252935294529552965297529852995300530153025303530453055306530753085309531053115312531353145315531653175318531953205321532253235324532553265327532853295330533153325333533453355336533753385339534053415342534353445345534653475348534953505351535253535354535553565357535853595360536153625363536453655366536753685369537053715372537353745375537653775378537953805381538253835384538553865387538853895390539153925393539453955396539753985399540054015402540354045405540654075408540954105411541254135414541554165417541854195420542154225423542454255426542754285429543054315432543354345435543654375438543954405441544254435444544554465447544854495450545154525453545454555456545754585459546054615462546354645465546654675468546954705471547254735474547554765477547854795480548154825483548454855486548754885489549054915492549354945495549654975498549955005501550255035504550555065507550855095510551155125513551455155516551755185519552055215522552355245525552655275528552955305531553255335534553555365537553855395540554155425543554455455546554755485549555055515552555355545555555655575558555955605561556255635564556555665567556855695570557155725573557455755576557755785579558055815582558355845585558655875588558955905591559255935594559555965597559855995600560156025603560456055606560756085609561056115612561356145615561656175618561956205621562256235624562556265627562856295630563156325633563456355636563756385639564056415642564356445645564656475648564956505651565256535654565556565657565856595660566156625663566456655666566756685669567056715672567356745675567656775678567956805681568256835684568556865687568856895690569156925693569456955696569756985699570057015702570357045705570657075708570957105711571257135714571557165717571857195720572157225723572457255726572757285729573057315732573357345735573657375738573957405741574257435744574557465747574857495750575157525753575457555756575757585759576057615762576357645765576657675768576957705771577257735774577557765777577857795780578157825783578457855786578757885789579057915792579357945795579657975798579958005801580258035804580558065807580858095810581158125813581458155816581758185819582058215822582358245825582658275828582958305831583258335834583558365837583858395840584158425843584458455846584758485849585058515852585358545855585658575858585958605861586258635864586558665867586858695870587158725873587458755876587758785879588058815882588358845885588658875888588958905891589258935894589558965897589858995900590159025903590459055906590759085909591059115912591359145915591659175918591959205921592259235924592559265927592859295930593159325933593459355936593759385939594059415942594359445945594659475948594959505951595259535954595559565957595859595960596159625963596459655966596759685969597059715972597359745975597659775978597959805981598259835984598559865987598859895990599159925993599459955996599759985999600060016002600360046005600660076008600960106011601260136014601560166017601860196020602160226023602460256026602760286029603060316032603360346035603660376038603960406041604260436044604560466047604860496050605160526053605460556056605760586059606060616062606360646065606660676068606960706071607260736074607560766077607860796080608160826083608460856086608760886089609060916092609360946095609660976098609961006101610261036104610561066107610861096110611161126113611461156116611761186119612061216122612361246125612661276128612961306131613261336134613561366137613861396140614161426143614461456146614761486149615061516152615361546155615661576158615961606161616261636164616561666167616861696170617161726173617461756176617761786179618061816182618361846185618661876188618961906191619261936194619561966197619861996200620162026203620462056206620762086209621062116212621362146215621662176218621962206221622262236224622562266227622862296230623162326233623462356236623762386239624062416242624362446245624662476248624962506251625262536254625562566257625862596260626162626263626462656266626762686269627062716272627362746275627662776278627962806281628262836284628562866287628862896290629162926293629462956296629762986299630063016302630363046305630663076308630963106311631263136314631563166317631863196320632163226323632463256326632763286329633063316332633363346335633663376338633963406341634263436344634563466347634863496350635163526353635463556356635763586359636063616362636363646365636663676368636963706371637263736374637563766377637863796380638163826383638463856386638763886389639063916392639363946395639663976398639964006401640264036404640564066407640864096410641164126413641464156416641764186419642064216422642364246425642664276428642964306431643264336434643564366437643864396440644164426443644464456446644764486449645064516452645364546455645664576458645964606461646264636464646564666467646864696470647164726473647464756476647764786479648064816482648364846485648664876488648964906491649264936494649564966497649864996500650165026503650465056506650765086509651065116512651365146515651665176518651965206521652265236524652565266527652865296530653165326533653465356536653765386539654065416542654365446545654665476548654965506551655265536554655565566557655865596560656165626563656465656566656765686569657065716572657365746575657665776578657965806581658265836584658565866587658865896590659165926593659465956596659765986599660066016602660366046605660666076608660966106611661266136614661566166617661866196620662166226623662466256626662766286629663066316632663366346635663666376638663966406641664266436644664566466647664866496650665166526653665466556656665766586659666066616662666366646665666666676668666966706671667266736674667566766677667866796680668166826683668466856686668766886689669066916692669366946695669666976698669967006701670267036704670567066707670867096710671167126713671467156716671767186719672067216722672367246725672667276728672967306731673267336734673567366737673867396740674167426743674467456746674767486749675067516752675367546755675667576758675967606761676267636764676567666767676867696770677167726773677467756776677767786779678067816782678367846785678667876788678967906791679267936794679567966797679867996800680168026803680468056806680768086809681068116812681368146815681668176818681968206821682268236824682568266827682868296830683168326833683468356836683768386839684068416842684368446845684668476848684968506851685268536854685568566857685868596860686168626863686468656866686768686869687068716872687368746875687668776878687968806881688268836884688568866887688868896890689168926893689468956896689768986899690069016902690369046905690669076908690969106911691269136914691569166917691869196920692169226923692469256926692769286929693069316932693369346935693669376938693969406941694269436944694569466947694869496950695169526953695469556956695769586959696069616962696369646965696669676968696969706971697269736974697569766977697869796980698169826983698469856986698769886989699069916992699369946995699669976998699970007001700270037004700570067007700870097010701170127013701470157016701770187019702070217022702370247025702670277028702970307031703270337034703570367037703870397040704170427043704470457046704770487049705070517052705370547055705670577058705970607061706270637064706570667067706870697070707170727073707470757076707770787079708070817082708370847085708670877088708970907091709270937094709570967097709870997100710171027103710471057106710771087109711071117112711371147115711671177118711971207121712271237124712571267127712871297130713171327133713471357136713771387139714071417142714371447145714671477148714971507151715271537154715571567157715871597160716171627163716471657166716771687169717071717172717371747175717671777178717971807181718271837184718571867187718871897190719171927193719471957196719771987199720072017202720372047205720672077208720972107211721272137214721572167217721872197220722172227223722472257226722772287229723072317232723372347235723672377238723972407241724272437244724572467247724872497250725172527253725472557256725772587259726072617262726372647265726672677268726972707271727272737274727572767277727872797280728172827283728472857286728772887289729072917292729372947295729672977298729973007301730273037304730573067307730873097310731173127313731473157316731773187319732073217322732373247325732673277328732973307331733273337334733573367337733873397340734173427343734473457346734773487349735073517352735373547355735673577358735973607361736273637364736573667367736873697370737173727373737473757376737773787379738073817382738373847385738673877388738973907391739273937394739573967397739873997400740174027403740474057406740774087409741074117412741374147415741674177418741974207421742274237424742574267427742874297430743174327433743474357436743774387439744074417442744374447445744674477448744974507451745274537454745574567457745874597460746174627463746474657466746774687469747074717472747374747475747674777478747974807481748274837484748574867487748874897490749174927493749474957496749774987499750075017502750375047505750675077508750975107511751275137514751575167517751875197520752175227523752475257526752775287529753075317532753375347535753675377538753975407541754275437544754575467547754875497550755175527553755475557556755775587559756075617562756375647565756675677568756975707571757275737574757575767577757875797580758175827583758475857586758775887589759075917592759375947595759675977598759976007601760276037604760576067607760876097610761176127613761476157616761776187619762076217622762376247625762676277628762976307631763276337634763576367637763876397640764176427643764476457646764776487649765076517652765376547655765676577658765976607661766276637664766576667667766876697670767176727673767476757676767776787679768076817682768376847685768676877688768976907691769276937694769576967697769876997700770177027703770477057706770777087709771077117712771377147715771677177718771977207721772277237724772577267727772877297730773177327733773477357736773777387739774077417742774377447745774677477748774977507751775277537754775577567757775877597760776177627763776477657766776777687769777077717772777377747775777677777778777977807781778277837784778577867787778877897790779177927793779477957796779777987799780078017802780378047805780678077808780978107811781278137814781578167817781878197820782178227823782478257826782778287829783078317832783378347835783678377838783978407841784278437844784578467847784878497850785178527853785478557856785778587859786078617862786378647865786678677868786978707871787278737874787578767877787878797880788178827883788478857886788778887889789078917892789378947895789678977898789979007901790279037904790579067907790879097910791179127913791479157916791779187919792079217922792379247925792679277928792979307931793279337934793579367937793879397940794179427943794479457946794779487949795079517952795379547955795679577958795979607961796279637964796579667967796879697970797179727973797479757976797779787979798079817982798379847985798679877988798979907991799279937994799579967997799879998000800180028003800480058006800780088009801080118012801380148015801680178018801980208021802280238024802580268027802880298030803180328033803480358036803780388039804080418042804380448045804680478048804980508051805280538054805580568057805880598060806180628063806480658066806780688069807080718072807380748075807680778078807980808081808280838084808580868087808880898090809180928093809480958096809780988099810081018102810381048105810681078108810981108111811281138114811581168117811881198120812181228123812481258126812781288129813081318132813381348135813681378138813981408141814281438144814581468147814881498150815181528153815481558156815781588159816081618162816381648165816681678168816981708171817281738174817581768177817881798180818181828183818481858186818781888189819081918192819381948195819681978198819982008201820282038204820582068207820882098210821182128213821482158216821782188219822082218222822382248225822682278228822982308231823282338234823582368237823882398240824182428243824482458246824782488249825082518252825382548255825682578258825982608261826282638264826582668267826882698270827182728273827482758276827782788279828082818282828382848285828682878288828982908291829282938294829582968297829882998300830183028303830483058306830783088309831083118312831383148315831683178318831983208321832283238324832583268327832883298330833183328333833483358336833783388339834083418342834383448345834683478348834983508351835283538354835583568357835883598360836183628363836483658366836783688369837083718372837383748375837683778378837983808381838283838384838583868387838883898390839183928393839483958396839783988399840084018402840384048405840684078408840984108411841284138414841584168417841884198420842184228423842484258426842784288429843084318432843384348435843684378438843984408441844284438444844584468447844884498450845184528453845484558456845784588459846084618462846384648465846684678468846984708471847284738474847584768477847884798480848184828483848484858486848784888489849084918492849384948495849684978498849985008501850285038504850585068507850885098510851185128513851485158516851785188519852085218522852385248525852685278528852985308531853285338534853585368537853885398540854185428543854485458546854785488549855085518552855385548555855685578558855985608561856285638564856585668567856885698570857185728573857485758576857785788579858085818582858385848585858685878588858985908591859285938594859585968597859885998600860186028603860486058606860786088609861086118612861386148615861686178618861986208621862286238624862586268627862886298630863186328633863486358636863786388639864086418642864386448645864686478648864986508651865286538654865586568657865886598660866186628663866486658666866786688669867086718672867386748675867686778678867986808681868286838684868586868687868886898690869186928693869486958696869786988699870087018702870387048705870687078708870987108711871287138714871587168717871887198720872187228723872487258726872787288729873087318732873387348735873687378738873987408741874287438744874587468747874887498750875187528753875487558756875787588759876087618762876387648765876687678768876987708771877287738774877587768777877887798780878187828783878487858786878787888789879087918792879387948795879687978798879988008801880288038804880588068807880888098810881188128813881488158816881788188819882088218822882388248825882688278828882988308831883288338834883588368837883888398840884188428843884488458846884788488849885088518852885388548855885688578858885988608861886288638864886588668867886888698870887188728873887488758876887788788879888088818882888388848885888688878888888988908891889288938894889588968897889888998900890189028903890489058906890789088909891089118912891389148915891689178918891989208921892289238924892589268927892889298930893189328933893489358936893789388939894089418942894389448945894689478948894989508951895289538954895589568957895889598960896189628963896489658966896789688969897089718972897389748975897689778978897989808981898289838984898589868987898889898990899189928993899489958996899789988999900090019002900390049005900690079008900990109011901290139014901590169017901890199020902190229023902490259026902790289029903090319032903390349035903690379038903990409041904290439044904590469047904890499050905190529053905490559056905790589059906090619062906390649065906690679068906990709071907290739074907590769077907890799080908190829083908490859086908790889089909090919092909390949095909690979098909991009101910291039104910591069107910891099110911191129113911491159116911791189119912091219122912391249125912691279128912991309131913291339134913591369137913891399140914191429143914491459146914791489149915091519152915391549155915691579158915991609161916291639164916591669167916891699170917191729173917491759176917791789179918091819182918391849185918691879188918991909191919291939194919591969197919891999200920192029203920492059206920792089209921092119212921392149215921692179218921992209221922292239224922592269227922892299230923192329233923492359236923792389239924092419242924392449245924692479248924992509251925292539254925592569257925892599260926192629263926492659266926792689269927092719272927392749275927692779278927992809281928292839284928592869287928892899290929192929293929492959296929792989299930093019302930393049305930693079308930993109311931293139314931593169317931893199320932193229323932493259326932793289329933093319332933393349335933693379338933993409341934293439344934593469347934893499350935193529353935493559356935793589359936093619362936393649365936693679368936993709371937293739374937593769377937893799380938193829383938493859386938793889389939093919392939393949395939693979398939994009401940294039404940594069407940894099410941194129413941494159416941794189419942094219422942394249425942694279428942994309431943294339434943594369437943894399440944194429443944494459446944794489449945094519452945394549455945694579458945994609461946294639464946594669467946894699470947194729473947494759476947794789479948094819482948394849485948694879488948994909491949294939494949594969497949894999500950195029503950495059506950795089509951095119512951395149515951695179518951995209521952295239524952595269527952895299530953195329533953495359536953795389539954095419542954395449545954695479548954995509551955295539554955595569557955895599560956195629563956495659566956795689569957095719572957395749575957695779578957995809581958295839584958595869587958895899590959195929593959495959596959795989599960096019602960396049605960696079608960996109611961296139614961596169617961896199620962196229623962496259626962796289629963096319632963396349635963696379638963996409641964296439644964596469647964896499650965196529653965496559656965796589659966096619662966396649665966696679668966996709671967296739674967596769677967896799680968196829683968496859686968796889689969096919692969396949695969696979698969997009701970297039704970597069707970897099710971197129713971497159716971797189719972097219722972397249725972697279728972997309731973297339734973597369737973897399740974197429743974497459746974797489749975097519752975397549755975697579758975997609761976297639764976597669767976897699770977197729773977497759776977797789779978097819782978397849785978697879788978997909791979297939794979597969797979897999800980198029803980498059806980798089809981098119812981398149815981698179818981998209821982298239824982598269827982898299830983198329833983498359836983798389839984098419842984398449845984698479848984998509851985298539854985598569857985898599860986198629863986498659866986798689869987098719872987398749875987698779878987998809881988298839884988598869887988898899890989198929893989498959896989798989899990099019902990399049905990699079908990999109911991299139914991599169917991899199920992199229923992499259926992799289929993099319932993399349935993699379938993999409941994299439944994599469947994899499950995199529953995499559956995799589959996099619962996399649965996699679968996999709971997299739974997599769977997899799980998199829983998499859986998799889989999099919992999399949995999699979998999910000100011000210003100041000510006100071000810009100101001110012100131001410015100161001710018100191002010021100221002310024100251002610027100281002910030100311003210033100341003510036100371003810039100401004110042100431004410045100461004710048100491005010051100521005310054100551005610057100581005910060100611006210063100641006510066100671006810069100701007110072100731007410075100761007710078100791008010081100821008310084100851008610087100881008910090100911009210093100941009510096100971009810099101001010110102101031010410105101061010710108101091011010111101121011310114101151011610117101181011910120101211012210123101241012510126101271012810129101301013110132101331013410135101361013710138101391014010141101421014310144101451014610147101481014910150101511015210153101541015510156101571015810159101601016110162101631016410165101661016710168101691017010171101721017310174101751017610177101781017910180101811018210183101841018510186101871018810189101901019110192101931019410195101961019710198101991020010201102021020310204102051020610207102081020910210102111021210213102141021510216102171021810219102201022110222102231022410225102261022710228102291023010231102321023310234102351023610237102381023910240102411024210243102441024510246102471024810249102501025110252102531025410255102561025710258102591026010261102621026310264102651026610267102681026910270102711027210273102741027510276102771027810279102801028110282102831028410285102861028710288102891029010291102921029310294102951029610297102981029910300103011030210303103041030510306103071030810309103101031110312103131031410315103161031710318103191032010321103221032310324103251032610327103281032910330103311033210333103341033510336103371033810339103401034110342103431034410345103461034710348103491035010351103521035310354103551035610357103581035910360103611036210363103641036510366103671036810369103701037110372103731037410375103761037710378103791038010381103821038310384103851038610387103881038910390103911039210393103941039510396103971039810399104001040110402104031040410405104061040710408104091041010411104121041310414104151041610417104181041910420104211042210423104241042510426104271042810429104301043110432104331043410435104361043710438104391044010441104421044310444104451044610447104481044910450104511045210453104541045510456104571045810459104601046110462104631046410465104661046710468104691047010471104721047310474104751047610477104781047910480104811048210483104841048510486104871048810489104901049110492104931049410495104961049710498104991050010501105021050310504105051050610507105081050910510105111051210513105141051510516105171051810519105201052110522105231052410525105261052710528105291053010531105321053310534105351053610537105381053910540105411054210543105441054510546105471054810549105501055110552105531055410555105561055710558105591056010561105621056310564105651056610567105681056910570105711057210573105741057510576105771057810579105801058110582105831058410585105861058710588105891059010591105921059310594105951059610597105981059910600106011060210603106041060510606106071060810609106101061110612106131061410615106161061710618106191062010621106221062310624106251062610627106281062910630106311063210633106341063510636106371063810639106401064110642106431064410645106461064710648106491065010651106521065310654106551065610657106581065910660106611066210663106641066510666106671066810669106701067110672106731067410675106761067710678106791068010681106821068310684106851068610687106881068910690106911069210693106941069510696106971069810699107001070110702107031070410705107061070710708107091071010711107121071310714107151071610717107181071910720107211072210723107241072510726107271072810729107301073110732107331073410735107361073710738107391074010741107421074310744107451074610747107481074910750107511075210753107541075510756107571075810759107601076110762107631076410765107661076710768107691077010771107721077310774107751077610777107781077910780107811078210783107841078510786107871078810789107901079110792107931079410795107961079710798107991080010801108021080310804108051080610807108081080910810108111081210813108141081510816108171081810819108201082110822108231082410825108261082710828108291083010831108321083310834108351083610837108381083910840108411084210843108441084510846108471084810849108501085110852108531085410855108561085710858108591086010861108621086310864108651086610867108681086910870108711087210873108741087510876108771087810879108801088110882108831088410885108861088710888108891089010891108921089310894108951089610897108981089910900109011090210903109041090510906109071090810909109101091110912109131091410915109161091710918109191092010921109221092310924109251092610927109281092910930109311093210933109341093510936109371093810939109401094110942109431094410945109461094710948109491095010951109521095310954109551095610957109581095910960109611096210963109641096510966109671096810969109701097110972109731097410975109761097710978109791098010981109821098310984109851098610987109881098910990109911099210993109941099510996109971099810999110001100111002110031100411005110061100711008110091101011011110121101311014110151101611017110181101911020110211102211023110241102511026110271102811029110301103111032110331103411035110361103711038110391104011041110421104311044110451104611047110481104911050110511105211053110541105511056110571105811059110601106111062110631106411065110661106711068110691107011071110721107311074110751107611077110781107911080110811108211083110841108511086110871108811089110901109111092110931109411095110961109711098110991110011101111021110311104111051110611107111081110911110111111111211113111141111511116111171111811119111201112111122111231112411125111261112711128111291113011131111321113311134111351113611137111381113911140111411114211143111441114511146111471114811149111501115111152111531115411155111561115711158111591116011161111621116311164111651116611167111681116911170111711117211173111741117511176111771117811179111801118111182111831118411185111861118711188111891119011191111921119311194111951119611197111981119911200112011120211203112041120511206112071120811209112101121111212112131121411215112161121711218112191122011221112221122311224112251122611227112281122911230112311123211233112341123511236112371123811239112401124111242112431124411245112461124711248112491125011251112521125311254112551125611257112581125911260112611126211263112641126511266112671126811269112701127111272112731127411275112761127711278112791128011281112821128311284112851128611287112881128911290112911129211293112941129511296112971129811299113001130111302113031130411305113061130711308113091131011311113121131311314113151131611317113181131911320113211132211323113241132511326113271132811329113301133111332113331133411335113361133711338113391134011341113421134311344113451134611347113481134911350113511135211353113541135511356113571135811359113601136111362113631136411365113661136711368113691137011371113721137311374113751137611377113781137911380113811138211383113841138511386113871138811389113901139111392113931139411395113961139711398113991140011401114021140311404114051140611407114081140911410114111141211413114141141511416114171141811419114201142111422114231142411425114261142711428114291143011431114321143311434114351143611437114381143911440114411144211443114441144511446114471144811449114501145111452114531145411455114561145711458114591146011461114621146311464114651146611467114681146911470114711147211473114741147511476114771147811479114801148111482114831148411485114861148711488114891149011491114921149311494114951149611497114981149911500115011150211503115041150511506115071150811509115101151111512115131151411515115161151711518115191152011521115221152311524115251152611527115281152911530115311153211533115341153511536115371153811539115401154111542115431154411545115461154711548115491155011551115521155311554115551155611557115581155911560115611156211563115641156511566115671156811569115701157111572115731157411575115761157711578115791158011581115821158311584115851158611587115881158911590115911159211593115941159511596115971159811599116001160111602116031160411605116061160711608116091161011611116121161311614116151161611617116181161911620116211162211623116241162511626116271162811629116301163111632116331163411635116361163711638116391164011641116421164311644116451164611647116481164911650116511165211653116541165511656116571165811659116601166111662116631166411665116661166711668116691167011671116721167311674116751167611677116781167911680116811168211683116841168511686116871168811689116901169111692116931169411695116961169711698116991170011701117021170311704117051170611707117081170911710117111171211713117141171511716117171171811719117201172111722117231172411725117261172711728117291173011731117321173311734117351173611737117381173911740117411174211743117441174511746117471174811749117501175111752117531175411755117561175711758117591176011761117621176311764117651176611767117681176911770117711177211773117741177511776117771177811779117801178111782117831178411785117861178711788117891179011791117921179311794117951179611797117981179911800118011180211803118041180511806118071180811809118101181111812118131181411815118161181711818118191182011821118221182311824118251182611827118281182911830118311183211833118341183511836118371183811839118401184111842118431184411845118461184711848118491185011851118521185311854118551185611857118581185911860118611186211863118641186511866118671186811869118701187111872118731187411875118761187711878118791188011881118821188311884118851188611887118881188911890118911189211893118941189511896118971189811899119001190111902119031190411905119061190711908119091191011911119121191311914119151191611917119181191911920119211192211923119241192511926119271192811929119301193111932119331193411935119361193711938119391194011941119421194311944119451194611947119481194911950119511195211953119541195511956119571195811959119601196111962119631196411965119661196711968119691197011971119721197311974119751197611977119781197911980119811198211983119841198511986119871198811989119901199111992119931199411995119961199711998119991200012001120021200312004120051200612007120081200912010120111201212013120141201512016120171201812019120201202112022120231202412025120261202712028120291203012031120321203312034120351203612037120381203912040120411204212043120441204512046120471204812049120501205112052120531205412055120561205712058120591206012061120621206312064120651206612067120681206912070120711207212073120741207512076120771207812079120801208112082120831208412085120861208712088120891209012091120921209312094120951209612097120981209912100121011210212103121041210512106121071210812109121101211112112121131211412115121161211712118121191212012121121221212312124121251212612127121281212912130121311213212133121341213512136121371213812139121401214112142121431214412145121461214712148121491215012151121521215312154121551215612157121581215912160121611216212163121641216512166121671216812169121701217112172121731217412175121761217712178121791218012181121821218312184121851218612187121881218912190121911219212193121941219512196121971219812199122001220112202122031220412205122061220712208122091221012211122121221312214122151221612217122181221912220122211222212223122241222512226122271222812229122301223112232122331223412235122361223712238122391224012241122421224312244122451224612247122481224912250122511225212253122541225512256122571225812259122601226112262122631226412265122661226712268122691227012271122721227312274122751227612277122781227912280122811228212283122841228512286122871228812289122901229112292122931229412295122961229712298122991230012301123021230312304123051230612307123081230912310123111231212313123141231512316123171231812319123201232112322123231232412325123261232712328123291233012331123321233312334123351233612337123381233912340123411234212343123441234512346123471234812349123501235112352123531235412355123561235712358123591236012361123621236312364123651236612367123681236912370123711237212373123741237512376123771237812379123801238112382123831238412385123861238712388123891239012391123921239312394123951239612397123981239912400124011240212403124041240512406124071240812409124101241112412124131241412415124161241712418124191242012421124221242312424124251242612427124281242912430124311243212433124341243512436124371243812439124401244112442124431244412445124461244712448124491245012451124521245312454124551245612457124581245912460124611246212463124641246512466124671246812469124701247112472124731247412475124761247712478124791248012481124821248312484124851248612487124881248912490124911249212493124941249512496124971249812499125001250112502125031250412505125061250712508125091251012511125121251312514125151251612517125181251912520125211252212523125241252512526125271252812529125301253112532125331253412535125361253712538125391254012541125421254312544125451254612547125481254912550125511255212553125541255512556125571255812559125601256112562125631256412565125661256712568125691257012571125721257312574125751257612577125781257912580125811258212583125841258512586125871258812589125901259112592125931259412595125961259712598125991260012601126021260312604126051260612607126081260912610126111261212613126141261512616126171261812619126201262112622126231262412625126261262712628126291263012631126321263312634126351263612637126381263912640126411264212643126441264512646126471264812649126501265112652126531265412655126561265712658126591266012661126621266312664126651266612667126681266912670126711267212673126741267512676126771267812679126801268112682126831268412685126861268712688126891269012691126921269312694126951269612697126981269912700127011270212703127041270512706127071270812709127101271112712127131271412715127161271712718127191272012721127221272312724127251272612727127281272912730127311273212733127341273512736127371273812739127401274112742127431274412745127461274712748127491275012751127521275312754127551275612757127581275912760127611276212763127641276512766127671276812769127701277112772127731277412775127761277712778127791278012781127821278312784127851278612787127881278912790127911279212793127941279512796127971279812799128001280112802128031280412805128061280712808128091281012811128121281312814128151281612817128181281912820128211282212823128241282512826128271282812829128301283112832128331283412835128361283712838128391284012841128421284312844128451284612847128481284912850128511285212853128541285512856128571285812859128601286112862128631286412865128661286712868128691287012871128721287312874128751287612877128781287912880128811288212883128841288512886128871288812889128901289112892128931289412895128961289712898128991290012901129021290312904129051290612907129081290912910129111291212913129141291512916129171291812919129201292112922129231292412925129261292712928129291293012931129321293312934129351293612937129381293912940129411294212943129441294512946129471294812949129501295112952129531295412955129561295712958129591296012961129621296312964129651296612967129681296912970129711297212973129741297512976129771297812979129801298112982129831298412985129861298712988129891299012991129921299312994129951299612997129981299913000130011300213003130041300513006130071300813009130101301113012130131301413015130161301713018130191302013021130221302313024130251302613027130281302913030130311303213033130341303513036130371303813039130401304113042130431304413045130461304713048130491305013051130521305313054130551305613057130581305913060130611306213063130641306513066130671306813069130701307113072130731307413075130761307713078130791308013081130821308313084130851308613087130881308913090130911309213093130941309513096130971309813099131001310113102131031310413105131061310713108131091311013111131121311313114131151311613117131181311913120131211312213123131241312513126131271312813129131301313113132131331313413135131361313713138131391314013141131421314313144131451314613147131481314913150131511315213153131541315513156131571315813159131601316113162131631316413165131661316713168131691317013171131721317313174131751317613177131781317913180131811318213183131841318513186131871318813189131901319113192131931319413195131961319713198131991320013201132021320313204132051320613207132081320913210132111321213213132141321513216132171321813219132201322113222132231322413225132261322713228132291323013231132321323313234132351323613237132381323913240132411324213243132441324513246132471324813249132501325113252132531325413255132561325713258132591326013261132621326313264132651326613267132681326913270132711327213273132741327513276132771327813279132801328113282132831328413285132861328713288132891329013291132921329313294132951329613297132981329913300133011330213303133041330513306133071330813309133101331113312133131331413315133161331713318133191332013321133221332313324133251332613327133281332913330133311333213333133341333513336133371333813339133401334113342133431334413345133461334713348133491335013351133521335313354133551335613357133581335913360133611336213363
  1. char *ckathv = "Authentication, 9.0.235, 16 Mar 2010";
  2. /*
  3. C K U A T H . C -- Authentication for C-Kermit
  4. Copyright (C) 1999, 2010,
  5. Trustees of Columbia University in the City of New York.
  6. All rights reserved. See the C-Kermit COPYING.TXT file or the
  7. copyright text in the ckcmai.c module for disclaimer and permissions.
  8. Author: Jeffrey E Altman (jaltman@secure-endpoints.com)
  9. Secure Endpoints Inc., New York City
  10. */
  11. /*
  12. * Additional copyrights included with affected code.
  13. */
  14. #ifdef HEIMDAL
  15. /*
  16. Turned off User to User support
  17. Turned off KDESTROY support
  18. Turned off KLIST support
  19. Turned off krb5_prompter() support
  20. Turned off ticket validation
  21. Turned off ticket renewal
  22. Turned off alternative cache support in k5_get_ccache()
  23. Remaining link problems:
  24. ckuath.o: In function `ck_krb5_initTGT':
  25. ckuath.o(.text+0x50c2): undefined reference to `krb5_string_to_deltat'
  26. ckuath.o(.text+0x516d): undefined reference to `krb5_string_to_deltat'
  27. ckuath.o(.text+0x51ef): undefined reference to `krb5_string_to_deltat'
  28. */
  29. #endif /* HEIMDAL */
  30. /*
  31. * Implements Kerberos 4/5, SRP, SSL, NTLM authentication and START_TLS
  32. */
  33. #include "ckcsym.h"
  34. #include "ckcdeb.h"
  35. #ifdef CK_SECURITY
  36. #define CKUATH_C
  37. #include "ckcker.h"
  38. #include "ckuusr.h"
  39. #include "ckucmd.h" /* For struct keytab */
  40. #include "ckcnet.h"
  41. #include "ckctel.h"
  42. char szUserNameRequested[UIDBUFLEN+1]; /* for incoming connections */
  43. char szUserNameAuthenticated[UIDBUFLEN+1];/* for incoming connections */
  44. char szHostName[UIDBUFLEN+1];
  45. char szUserName[UIDBUFLEN+1];
  46. static char szIP[16];
  47. static int validUser = AUTH_REJECT; /* User starts out invalid */
  48. int authentication_version = AUTHTYPE_NULL;
  49. int accept_complete = 0;
  50. #ifdef CK_AUTHENTICATION
  51. #ifdef CK_SSL
  52. #ifdef KRB5
  53. #define TLS_VERIFY
  54. #endif /* KRB5 */
  55. #endif /* CK_SSL */
  56. #ifdef CK_DES
  57. #ifdef CK_SSL
  58. #ifndef LIBDES
  59. #define LIBDES
  60. #endif /* LIBDES */
  61. #endif /* CK_SSL */
  62. #endif /* CK_DES */
  63. #ifdef CRYPT_DLL
  64. #ifndef LIBDES
  65. #define LIBDES
  66. #endif /* LIBDES */
  67. #ifdef OS2
  68. #ifdef NT
  69. #include <windows.h>
  70. #else /* NT */
  71. #define INCL_DOSMODULEMGR
  72. #include <os2.h>
  73. #endif /* NT */
  74. #endif /* OS2 */
  75. #endif /* CRYPT_DLL */
  76. #ifdef NT
  77. #define KRB5_AUTOCONF__
  78. #define NTLM
  79. #endif /* NT */
  80. #ifdef CK_KERBEROS
  81. #define KINIT
  82. #ifndef HEIMDAL
  83. #define KLIST
  84. #define KDESTROY
  85. #endif /* HEIMDAL */
  86. #define CHECKADDRS
  87. #else /* CK_KERBEROS */
  88. #ifdef KRB4
  89. #undef KRB4
  90. #endif /* KRB4 */
  91. #ifdef KRB5
  92. #undef KRB5
  93. #endif /* KRB5 */
  94. #ifdef KRB524
  95. #undef KRB524
  96. #endif /* KRB524 */
  97. #endif /* CK_KERBEROS */
  98. #include <stdlib.h>
  99. #include <string.h>
  100. #include <stdio.h>
  101. #include <time.h>
  102. #include <fcntl.h>
  103. #include <errno.h>
  104. #ifndef malloc
  105. #ifndef VMS
  106. #ifndef FREEBSD4
  107. #ifndef OpenBSD
  108. #ifdef MACOSX
  109. #include <sys/malloc.h>
  110. #else /* MACOSX */
  111. #include <malloc.h>
  112. #endif /* MACOSX */
  113. #endif /* OpenBSD */
  114. #endif /* FREEBSD4 */
  115. #endif /* VMS */
  116. #endif /* malloc */
  117. #ifdef OS2
  118. #include <io.h>
  119. #endif /* OS2 */
  120. #ifdef KRB5
  121. #ifdef HEIMDAL
  122. #ifdef printf
  123. #define saveprintf printf
  124. #undef printf
  125. #endif /* printf */
  126. #include "krb5.h"
  127. #include "com_err.h"
  128. #ifdef saveprintf
  129. #define printf saveprintf
  130. #endif /* saveprintf */
  131. #else /* HEIMDAL */
  132. #include "krb5.h"
  133. #include "profile.h"
  134. #include "com_err.h"
  135. #ifdef KRB5_GET_INIT_CREDS_OPT_TKT_LIFE
  136. #define KRB5_HAVE_GET_INIT_CREDS
  137. #else
  138. #define krb5_free_unparsed_name(con,val) krb5_xfree((char *)(val))
  139. #endif
  140. #ifndef KRB5_HAVE_GET_INIT_CREDS
  141. #define krb5_free_data_contents(c,v) krb5_xfree((char *)(v)->data)
  142. #endif
  143. #endif /* HEIMDAL */
  144. #ifdef HAVE_PWD_H
  145. #include <pwd.h>
  146. #endif
  147. #endif /* KRB5 */
  148. #ifdef KRB4
  149. #define des_cblock Block
  150. #define const_des_cblock const Block
  151. #define des_key_schedule Schedule
  152. #ifdef KRB524
  153. #ifdef NT
  154. #define _WINDOWS
  155. #endif /* NT */
  156. #include "kerberosIV/krb.h"
  157. #ifndef OS2
  158. #ifdef KRB524_CONV
  159. #include "krb524.h"
  160. #endif /* KRB524_CONV */
  161. _PROTOTYP(const char * krb_get_err_text_entry, (int));
  162. #endif /* OS2 */
  163. #else /* KRB524 */
  164. #ifdef SOLARIS
  165. #ifndef sun
  166. /* for some reason the Makefile entries for the Solaris systems have -Usun */
  167. #define sun
  168. #endif /* sun */
  169. #endif /* SOLARIS */
  170. #include "krb.h"
  171. #define krb_get_err_text_entry krb_get_err_text
  172. #endif /* KRB524 */
  173. #else /* KRB4 */
  174. #ifdef CK_SSL
  175. #define des_cblock Block
  176. #ifdef COMMENT
  177. #define const_des_cblock const Block
  178. #endif /* COMMENT */
  179. #define des_key_schedule Schedule
  180. #endif /* CK_SSL */
  181. #endif /* KRB4 */
  182. #include "ckuath.h"
  183. #ifdef CK_KERBEROS
  184. #ifndef KRB5
  185. #define NOBLOCKDEF
  186. #else /* KRB5 */
  187. #ifdef KRB524
  188. #define NOBLOCKDEF
  189. #endif /* KRB524 */
  190. #endif /* KRB5 */
  191. #endif /* CK_KERBEROS */
  192. #include "ckuat2.h"
  193. #ifdef CK_SSL
  194. #ifdef LIBDES
  195. #ifdef OPENSSL_097
  196. #ifdef CK_DES
  197. #define OPENSSL_ENABLE_OLD_DES_SUPPORT
  198. #include <openssl/des.h>
  199. #endif /* CK_DES */
  200. #endif /* OPENSSL_097 */
  201. #ifndef HEADER_DES_H
  202. #define HEADER_DES_H
  203. #endif /* HEADER_DES_H */
  204. #endif /* LIBDES */
  205. #include "ck_ssl.h"
  206. extern int ssl_finished_messages;
  207. #endif /* SSL */
  208. #define PWD_SZ 128
  209. #ifndef LIBDES
  210. #ifdef UNIX
  211. #define des_set_random_generator_seed(x) des_init_random_number_generator(x)
  212. #endif /* UNIX */
  213. #else /* LIBDES */
  214. #define des_fixup_key_parity des_set_odd_parity
  215. #endif /* LIBDES */
  216. #ifdef OS2
  217. #ifdef CK_ENCRYPTION
  218. #define MAP_DES
  219. #endif /* CK_ENCRYPTION */
  220. #ifdef KRB4
  221. #define MAP_KRB4
  222. #endif /* KRB4 */
  223. #ifdef SRPDLL
  224. #define MAP_SRP
  225. #endif /* SRPDLL */
  226. #ifdef KRB5
  227. #define MAP_KRB5
  228. #endif /* KRB5 */
  229. #ifdef CRYPT_DLL
  230. #define MAP_CRYPT
  231. #endif /* CRYPT_DLL */
  232. #define MAP_NTLM
  233. #include "ckoath.h"
  234. #include "ckosyn.h"
  235. #endif /* OS2 */
  236. /*
  237. * Globals
  238. */
  239. int auth_type_user[AUTHTYPLSTSZ] = {AUTHTYPE_AUTO, AUTHTYPE_NULL};
  240. int auth_how=0;
  241. int auth_crypt=0;
  242. int auth_fwd=0;
  243. /* These are state completion variables */
  244. static int mutual_complete = 0;
  245. #ifdef KRB4
  246. #ifdef OS2
  247. static LEASH_CREDENTIALS cred;
  248. #else /* OS2 */
  249. static CREDENTIALS cred;
  250. #endif /* OS2 */
  251. static KTEXT_ST k4_auth;
  252. static char k4_name[ANAME_SZ];
  253. static AUTH_DAT k4_adat = { 0 };
  254. static MSG_DAT k4_msg_data;
  255. #ifdef CK_ENCRYPTION
  256. static Block k4_session_key = { 0 };
  257. static Schedule k4_sched;
  258. static Block k4_challenge = { 0 };
  259. #ifdef MIT_CURRENT
  260. static krb5_keyblock k4_krbkey;
  261. #endif /* MIT_CURRENT */
  262. #endif /* ENCRYPTION */
  263. #define KRB4_SERVICE_NAME "rcmd"
  264. _PROTOTYP(static int k4_auth_send,(VOID));
  265. _PROTOTYP(static int k4_auth_reply,(unsigned char *, int));
  266. _PROTOTYP(static int k4_auth_is,(unsigned char *, int));
  267. #endif /* KRB4 */
  268. #ifdef KRB5
  269. static krb5_data k5_auth;
  270. static krb5_auth_context auth_context;
  271. static krb5_keyblock *k5_session_key = NULL;
  272. static krb5_ticket *k5_ticket = NULL;
  273. #ifndef KRB5_SERVICE_NAME
  274. #define KRB5_SERVICE_NAME "host"
  275. #ifdef MACOSX
  276. #define MIT_CURRENT 1
  277. #define decode_krb5_ticket krb5_decode_ticket
  278. #define krb5_read_message ck_krb5_read_message
  279. #define krb5_write_message ck_krb5_write_message
  280. #endif /* MACOSX */
  281. #endif
  282. _PROTOTYP(static int k5_auth_send,(int,int,int));
  283. _PROTOTYP(static int k5_auth_reply,(int, unsigned char *, int));
  284. _PROTOTYP(static int k5_auth_is,(int,unsigned char *, int));
  285. _PROTOTYP(static int SendK5AuthSB,(int, void *, int));
  286. #ifdef TLS_VERIFY
  287. static int krb5_tls_verified = 0;
  288. #endif /* TLS_VERIFY */
  289. #endif /* KRB5 */
  290. #ifdef GSSAPI_KRB5
  291. #include <gssapi/gssapi.h>
  292. #include <gssapi/gssapi_generic.h>
  293. #include <gssapi/gssapi_krb5.h>
  294. static gss_ctx_id_t gcontext;
  295. #define GSS_BUFSIZ 4096
  296. static gss_buffer_desc gss_send_tok, gss_recv_tok, *gss_token_ptr;
  297. static char gss_stbuf[GSS_BUFSIZ];
  298. static gss_name_t gss_target_name;
  299. static struct gss_channel_bindings_struct gss_chan;
  300. _PROTOTYP(static int gssk5_auth_send,(int,int,int));
  301. _PROTOTYP(static int gssk5_auth_reply,(int, unsigned char *, int));
  302. _PROTOTYP(static int gssk5_auth_is,(int,unsigned char *, int));
  303. _PROTOTYP(static int SendGSSK5AuthSB,(int, void *, int));
  304. #endif /* GSSAPI_KRB5 */
  305. #ifdef CK_SRP
  306. #ifdef PRE_SRP_1_7_3
  307. _PROTOTYP(static int srp_reply,(int, unsigned char *, int));
  308. _PROTOTYP(static int srp_is,(int, unsigned char *, int));
  309. #else /* PRE_SRP_1_7_3 */
  310. _PROTOTYP(static int new_srp_reply,(int, unsigned char *, int));
  311. _PROTOTYP(static int new_srp_is,(int, unsigned char *, int));
  312. #endif /* PRE_SRP_1_7_3 */
  313. #endif /* SRP */
  314. #ifdef CK_ENCRYPTION
  315. int encrypt_flag = 1;
  316. #endif
  317. #ifdef FORWARD
  318. int forward_flag = 0; /* forward tickets? */
  319. int forwardable_flag = 1; /* get forwardable tickets to forward? */
  320. int forwarded_tickets = 0; /* were tickets forwarded? */
  321. #endif
  322. static unsigned char str_data[4096] = { IAC, SB, TELOPT_AUTHENTICATION, 0,
  323. AUTHTYPE_KERBEROS_V5, };
  324. #define AUTHTMPBL 2048
  325. static char strTmp[AUTHTMPBL+1];
  326. static char szLocalHostName[UIDBUFLEN+1];
  327. static kstream g_kstream=NULL;
  328. #ifdef KRB5
  329. krb5_context k5_context=NULL;
  330. static krb5_creds * ret_cred=NULL;
  331. static krb5_context telnet_context=NULL;
  332. static char * telnet_krb5_realm = NULL;
  333. static krb5_principal fwd_server = NULL;
  334. #endif /* KRB5 */
  335. #ifdef CK_SRP
  336. #ifdef PRE_SRP_1_4_4
  337. #ifndef PRE_SRP_1_4_5
  338. #define PRE_SRP_1_4_5
  339. #endif /* PRE_SRP_1_4_5 */
  340. #endif /* PRE_SRP_1_4_5 */
  341. #ifdef PRE_SRP_1_4_5
  342. #ifndef PRE_SRP_1_7_3
  343. #define PRE_SRP_1_7_3
  344. #endif /* PRE_SRP_1_7_3 */
  345. #endif /* PRE_SRP_1_4_5 */
  346. #include <t_pwd.h>
  347. #include <t_client.h>
  348. #include <t_server.h>
  349. static struct t_server * ts = NULL;
  350. static struct t_client * tc = NULL;
  351. #ifdef PRE_SRP_1_4_4
  352. static struct t_pw * tpw = NULL;
  353. static struct t_conf * tconf = NULL;
  354. #endif /* PRE_SRP_1_4_4 */
  355. #ifndef PRE_SRP_1_7_3
  356. #ifndef STDC_HEADERS
  357. #define STDC_HEADERS 1
  358. #endif /* STDC_HEADERS */
  359. #include <srp.h>
  360. static SRP * s_srp = NULL;
  361. static cstr * s_key = NULL;
  362. static SRP * c_srp = NULL;
  363. static cstr * c_key = NULL;
  364. #endif /* PRE_SRP_1_7_3 */
  365. static int srp_waitresp = 0; /* Flag to indicate readiness for response */
  366. static char srp_passwd[PWD_SZ];
  367. #endif /* CK_SRP */
  368. #ifdef CK_KERBEROS
  369. #ifdef RLOGCODE
  370. #define OPTS_FORWARD_CREDS 0x00000020
  371. #define OPTS_FORWARDABLE_CREDS 0x00000010
  372. #define KCMD_KEYUSAGE 1026
  373. #define RLOG_BUFSIZ 5120
  374. static int rlog_encrypt = 0;
  375. char des_inbuf[2*RLOG_BUFSIZ]; /* needs to be > largest read size */
  376. char des_outpkt[2*RLOG_BUFSIZ+4]; /* needs to be > largest write size */
  377. #ifdef KRB5
  378. krb5_data desinbuf,desoutbuf;
  379. krb5_encrypt_block eblock; /* eblock for encrypt/decrypt */
  380. static krb5_data encivec_i[2], encivec_o[2];
  381. enum krb5_kcmd_proto {
  382. /* Old protocol: DES encryption only. No subkeys. No protection
  383. for cleartext length. No ivec supplied. OOB hacks used for
  384. rlogin. Checksum may be omitted at connection startup. */
  385. KCMD_OLD_PROTOCOL = 1,
  386. /* New protocol: Any encryption scheme. Client-generated subkey
  387. required. Prepend cleartext-length to cleartext data (but don't
  388. include it in count). Starting ivec defined, chained. In-band
  389. signalling. Checksum required. */
  390. KCMD_NEW_PROTOCOL,
  391. /* Hack: Get credentials, and use the old protocol iff the session
  392. key type is single-DES. */
  393. KCMD_PROTOCOL_COMPAT_HACK,
  394. KCMD_UNKNOWN_PROTOCOL
  395. };
  396. enum krb5_kcmd_proto krb5_rlog_ver = KCMD_PROTOCOL_COMPAT_HACK;
  397. #endif /* KRB5 */
  398. #endif /* RLOGCODE */
  399. static char storage[65536]; /* storage for the decryption */
  400. static int nstored = 0;
  401. static char *store_ptr = storage;
  402. extern char * krb5_d_principal; /* Default principal */
  403. extern char * krb5_d_instance; /* Default instance */
  404. extern char * krb5_d_realm; /* Default realm */
  405. extern char * krb5_d_cc; /* Default credentials cache */
  406. extern char * krb5_d_srv; /* Default service name */
  407. extern int krb5_d_lifetime; /* Default lifetime */
  408. extern int krb5_d_forwardable;
  409. extern int krb5_d_proxiable;
  410. extern int krb5_d_renewable;
  411. extern int krb5_autoget;
  412. extern int krb5_checkaddrs;
  413. extern int krb5_d_getk4;
  414. extern int krb5_d_no_addresses;
  415. extern char * k5_keytab;
  416. extern int krb5_errno;
  417. extern char * krb5_errmsg;
  418. extern char * krb4_d_principal; /* Default principal */
  419. extern char * krb4_d_realm; /* Default realm */
  420. extern char * krb4_d_srv; /* Default service name */
  421. extern int krb4_d_lifetime; /* Default lifetime */
  422. extern int krb4_d_preauth;
  423. extern char * krb4_d_instance;
  424. extern int krb4_autoget;
  425. extern int krb4_checkaddrs;
  426. extern char * k4_keytab;
  427. extern int krb4_errno;
  428. extern char * krb4_errmsg;
  429. #endif /* CK_KERBEROS */
  430. extern char tn_msg[], hexbuf[]; /* from ckcnet.c */
  431. extern CHAR pwbuf[];
  432. extern int pwflg, pwcrypt;
  433. extern int deblog, debses, tn_deb;
  434. extern int sstelnet, inserver;
  435. #ifdef CK_LOGIN
  436. extern int ckxanon;
  437. #endif /* CK_LOGIN */
  438. extern int tn_auth_how;
  439. extern int tn_auth_enc;
  440. #ifdef CK_ENCRYPTION
  441. extern int cx_type;
  442. #endif /* CK_ENCRYPTION */
  443. extern int quiet, ttyfd, ttnproto;
  444. int
  445. ck_gssapi_is_installed()
  446. {
  447. #ifdef KRB5
  448. #ifdef OS2
  449. return(hGSSAPI != NULL);
  450. #else /* OS2 */
  451. return(1);
  452. #endif /* OS2 */
  453. #else /* KRB5 */
  454. return(0);
  455. #endif /* KRB5 */
  456. }
  457. int
  458. ck_krb5_is_installed()
  459. {
  460. #ifdef KRB5
  461. #ifdef OS2
  462. return(hKRB5_32 != NULL);
  463. #else /* OS2 */
  464. return(1);
  465. #endif /* OS2 */
  466. #else /* KRB5 */
  467. return(0);
  468. #endif /* KRB5 */
  469. }
  470. int
  471. ck_krb5_is_installed_as_server()
  472. {
  473. #ifdef KRB5
  474. #ifdef HEIMDAL
  475. krb5_error_code ret;
  476. krb5_keytab kt;
  477. krb5_kt_cursor cursor;
  478. ret = krb5_kt_default(k5_context, &kt);
  479. if ( ret ) {
  480. krb5_kt_close(k5_context, kt);
  481. return(0);
  482. } else {
  483. krb5_kt_end_seq_get(k5_context, kt, &cursor);
  484. krb5_kt_close(k5_context, kt);
  485. return(1);
  486. }
  487. #else /* HEIMDAL */
  488. #ifndef COMMENT
  489. char ktname[CKMAXPATH]="";
  490. if ( k5_keytab ) {
  491. ckstrncpy(ktname,k5_keytab,CKMAXPATH);
  492. } else {
  493. krb5_error_code code;
  494. if ( k5_context == NULL)
  495. if (krb5_init_context(&k5_context))
  496. return(0);
  497. code = krb5_kt_default_name(k5_context,ktname,CKMAXPATH);
  498. debug(F101,"krb5_kt_default_name","",code);
  499. if ( code ) {
  500. /* We can't check the existence of the file since we can't */
  501. /* determine the file name. So we return TRUE and let */
  502. /* Krb5 be offered to the user even though it may fail later */
  503. return(1);
  504. }
  505. }
  506. if ( !strncmp("FILE:",ktname,5) ) {
  507. if ( zchki(&ktname[5]) > 0 )
  508. return(1);
  509. else
  510. return(0);
  511. } else {
  512. if (ktname[0])
  513. return(1);
  514. else
  515. return(0);
  516. }
  517. #else /* COMMENT */
  518. krb5_error_code krb5rc = KRB5KRB_ERR_GENERIC;
  519. krb5_context krb5context = NULL;
  520. krb5_ccache krb5ccdef = NULL;
  521. krb5_creds krb5creds, *krb5credsp = NULL;
  522. int rc = 0;
  523. if ( !ck_krb5_is_installed() )
  524. return(0);
  525. memset((char *)&krb5creds, 0, sizeof(krb5creds));
  526. if ((krb5rc = krb5_init_context(&krb5context)) != 0)
  527. goto err;
  528. if ((krb5rc = krb5_sname_to_principal(krb5context,
  529. szHostName,
  530. krb5_d_srv ?
  531. krb5_d_srv :
  532. KRB5_SERVICE_NAME,
  533. KRB5_NT_SRV_HST,
  534. &krb5creds.server)) != 0)
  535. goto err;
  536. if ((krb5rc = krb5_cc_default(krb5context, &krb5ccdef)) != 0)
  537. goto err;
  538. if ((krb5rc = krb5_cc_get_principal(krb5context, krb5ccdef,
  539. &krb5creds.client)) != 0)
  540. goto err;
  541. if ((krb5rc = krb5_get_credentials(krb5context, 0, krb5ccdef,
  542. &krb5creds, &krb5credsp)) != 0)
  543. goto err;
  544. rc = 1;
  545. err:
  546. if (krb5creds.client)
  547. krb5_free_principal(krb5context, krb5creds.client);
  548. if (krb5creds.server)
  549. krb5_free_principal(krb5context, krb5creds.server);
  550. if (krb5context)
  551. krb5_free_context(krb5context);
  552. return(rc);
  553. #endif /* COMMENT */
  554. #endif /* HEIMDAL */
  555. #else /* KRB5 */
  556. return(0);
  557. #endif /* KRB5 */
  558. }
  559. int
  560. ck_krb4_is_installed()
  561. {
  562. #ifdef KRB4
  563. #ifdef OS2
  564. return(hKRB4_32 != NULL);
  565. #else /* OS2 */
  566. return(1);
  567. #endif /* OS2 */
  568. #else /* KRB4 */
  569. return(0);
  570. #endif /* KRB4 */
  571. }
  572. int
  573. ck_krb4_is_installed_as_server()
  574. {
  575. if ( !ck_krb4_is_installed() )
  576. return(0);
  577. #ifdef KRB4
  578. if ( !k4_keytab ) {
  579. #ifdef NT
  580. char name[CKMAXPATH]="";
  581. DWORD len = CKMAXPATH;
  582. len = GetWindowsDirectory(name,len);
  583. if ( len > 0 )
  584. ckstrncat(name,"/srvtab",CKMAXPATH);
  585. if ( name[0] )
  586. makestr(&k4_keytab,name);
  587. #else /* NT */
  588. makestr(&k4_keytab,"/etc/srvtab");
  589. #endif /* NT */
  590. }
  591. if ( !k4_keytab )
  592. return(0);
  593. if ( zchki(k4_keytab) > 0 )
  594. return(1);
  595. #ifdef KRB524
  596. else if (ck_krb5_is_installed_as_server())
  597. return(1);
  598. #endif /* KRB524 */
  599. else
  600. return(0);
  601. #endif /* KRB4 */
  602. }
  603. int
  604. ck_srp_is_installed_as_server()
  605. {
  606. #ifdef CK_SRP
  607. #ifdef SRPDLL
  608. if ( hSRP == NULL )
  609. return(0);
  610. #endif /* SRPDLL */
  611. #ifdef COMMENT
  612. /* This is the new API as of 1.7.4. However, all it does
  613. is allocate a data structure. It can never fail.
  614. */
  615. {
  616. SRP * s_srp = SRP_new(SRP_RFC2945_server_method());
  617. if ( s_srp ) {
  618. SRP_free(s_srp);
  619. s_srp = NULL;
  620. return(1);
  621. }
  622. return(0);
  623. }
  624. #else /* COMMENT */
  625. {
  626. struct t_pw * tpw = NULL;
  627. struct t_conf * tconf = NULL;
  628. if((tconf = t_openconf(NULL)) == NULL)
  629. return(0);
  630. if((tpw = t_openpw(NULL)) == NULL) {
  631. t_closeconf(tconf);
  632. return(0);
  633. }
  634. t_closeconf(tconf);
  635. t_closepw(tpw);
  636. return(1);
  637. }
  638. #endif /* COMMENT */
  639. #else /* SRP */
  640. return(0);
  641. #endif /* SRP */
  642. }
  643. int
  644. ck_srp_is_installed()
  645. {
  646. #ifdef CK_SRP
  647. #ifdef SRPDLL
  648. if ( hSRP == NULL )
  649. return(0);
  650. #endif /* SRPDLL */
  651. return(1);
  652. #else /* CK_SRP */
  653. return(0);
  654. #endif /* CK_SRP */
  655. }
  656. int
  657. ck_krypto_is_installed()
  658. {
  659. #ifdef CK_SRP
  660. #ifdef OS2
  661. if ( hLIBKRYPTO == NULL )
  662. return(0);
  663. #endif /* OS2 */
  664. return(1);
  665. #else /* CK_SRP */
  666. return(0);
  667. #endif /* CK_SRP */
  668. }
  669. int
  670. ck_crypt_is_installed()
  671. {
  672. #ifdef CK_ENCRYPTION
  673. #ifdef CRYPT_DLL
  674. return(hCRYPT != NULL);
  675. #else /* CRYPT_DLL */
  676. return(1);
  677. #endif /* CRYPT_DLL */
  678. #else /* ENCRYPTION */
  679. return(0);
  680. #endif /* ENCRYPTION */
  681. }
  682. int
  683. ck_ntlm_is_installed()
  684. {
  685. #ifdef NT
  686. return(hSSPI != NULL);
  687. #else /* NT */
  688. return(0);
  689. #endif /* NT */
  690. }
  691. int
  692. ck_tn_auth_valid()
  693. {
  694. return(validUser);
  695. }
  696. /* C K _ K R B _ A U T H _ I N _ P R O G R E S S
  697. *
  698. * Is an authentication negotiation still in progress?
  699. *
  700. */
  701. int
  702. #ifdef CK_ANSIC
  703. ck_tn_auth_in_progress(void)
  704. #else
  705. ck_tn_auth_in_progress()
  706. #endif
  707. {
  708. switch (authentication_version) {
  709. case AUTHTYPE_AUTO:
  710. return(1);
  711. case AUTHTYPE_NULL:
  712. return(0);
  713. #ifdef KRB4
  714. case AUTHTYPE_KERBEROS_V4:
  715. if (!accept_complete) {
  716. debug(F100,"ck_auth_in_progress() Kerberos 4 !accept_complete",
  717. "",0);
  718. return(1);
  719. }
  720. else if ((auth_how & AUTH_HOW_MASK) && !mutual_complete) {
  721. debug(F100,"ck_auth_in_progress() Kerberos 4 !mutual_complete",
  722. "",0);
  723. return(1);
  724. }
  725. else
  726. return(0);
  727. #endif /* KRB4 */
  728. #ifdef KRB5
  729. case AUTHTYPE_KERBEROS_V5:
  730. if (!accept_complete) {
  731. debug(F100,"ck_auth_in_progress() Kerberos 5 !accept_complete",
  732. "",0);
  733. return(1);
  734. }
  735. else if ((auth_how & AUTH_HOW_MASK) && !mutual_complete) {
  736. debug(F100,"ck_auth_in_progress() Kerberos 5 !mutual_complete",
  737. "",0);
  738. return(1);
  739. }
  740. else
  741. return(0);
  742. #ifdef GSSAPI_K5
  743. case AUTHTYPE_GSSAPI_KRB5:
  744. if (!accept_complete) {
  745. debug(F100,
  746. "ck_auth_in_progress() GSSAPI Kerberos 5 !accept_complete",
  747. "",
  748. 0
  749. );
  750. return(1);
  751. }
  752. else if ((auth_how & AUTH_HOW_MASK) && !mutual_complete) {
  753. debug(F100,
  754. "ck_auth_in_progress() GSSAPI Kerberos 5 !mutual_complete",
  755. "",
  756. 0
  757. );
  758. return(1);
  759. } else
  760. return(0);
  761. break;
  762. #endif /* GSSAPI_K5 */
  763. #endif /* KRB5 */
  764. #ifdef CK_SRP
  765. case AUTHTYPE_SRP:
  766. if (!accept_complete || srp_waitresp)
  767. return(1);
  768. else
  769. return(0);
  770. #endif /* CK_SRP */
  771. #ifdef NTLM
  772. case AUTHTYPE_NTLM:
  773. if (!accept_complete) {
  774. debug(F100,"ck_auth_in_progress() NTLM !accept_complete",
  775. "",0);
  776. return(1);
  777. }
  778. else
  779. return(0);
  780. #endif /* NTLM */
  781. case AUTHTYPE_SSL:
  782. if (!accept_complete) {
  783. debug(F100,"ck_auth_in_progress() SSL !accept_complete",
  784. "",0);
  785. return(1);
  786. }
  787. else
  788. return(0);
  789. default:
  790. return(0);
  791. }
  792. return(0);
  793. }
  794. /* C K _ K R B _ T N _ A U T H _ R E Q U E S T
  795. *
  796. * Builds a Telnet Authentication Send Negotiation providing the
  797. * list of supported authentication methods. To be used only
  798. * when accepting incoming connections as only the server (DO) side of the
  799. * Telnet negotiation is allowed to send an AUTH SEND.
  800. *
  801. * Returns: 0 on success and -1 on failure
  802. */
  803. static unsigned char str_request[64] = { IAC, SB,
  804. TELOPT_AUTHENTICATION,
  805. TELQUAL_SEND };
  806. #ifdef GSSAPI_K5
  807. static int
  808. ck_tn_auth_request_gsskrb5(int i)
  809. {
  810. if (ck_gssapi_is_installed() && ck_krb5_is_installed_as_server()) {
  811. if ( (tn_auth_how == TN_AUTH_HOW_ANY ||
  812. tn_auth_how == TN_AUTH_HOW_MUTUAL) &&
  813. (tn_auth_enc == TN_AUTH_ENC_ANY ||
  814. tn_auth_enc == TN_AUTH_ENC_EXCH) ) {
  815. str_request[i++] = AUTHTYPE_KERBEROS_V5;
  816. str_request[i] = AUTH_CLIENT_TO_SERVER | AUTH_HOW_MUTUAL;
  817. str_request[i] |= AUTH_ENCRYPT_AFTER_EXCHANGE;
  818. if ( deblog || tn_deb || debses )
  819. ckstrncat(tn_msg,
  820. "KERBEROS_V5 CLIENT_TO_SERVER|MUTUAL|ENCRYPT_AFTER_EXCHANGE ",
  821. TN_MSG_LEN);
  822. i++;
  823. }
  824. }
  825. }
  826. #endif /* GSSAPI_K5 */
  827. #ifdef KRB5
  828. static int
  829. ck_tn_auth_request_krb5(int i)
  830. {
  831. if (ck_krb5_is_installed_as_server()) {
  832. #ifdef CK_SSL
  833. if ( ck_ssleay_is_installed() &&
  834. (tls_active_flag || ssl_active_flag) &&
  835. ssl_finished_messages )
  836. {
  837. #ifdef USE_INI_CRED_FWD
  838. if ( forward_flag &&
  839. (tn_auth_how == TN_AUTH_HOW_ANY ||
  840. tn_auth_how == TN_AUTH_HOW_MUTUAL) &&
  841. (tn_auth_enc == TN_AUTH_ENC_ANY ||
  842. tn_auth_enc == TN_AUTH_ENC_TELOPT)
  843. )
  844. {
  845. str_request[i++] = AUTHTYPE_KERBEROS_V5;
  846. str_request[i] = AUTH_CLIENT_TO_SERVER | AUTH_HOW_MUTUAL;
  847. str_request[i] |= AUTH_ENCRYPT_START_TLS;
  848. str_request[i] |= INI_CRED_FWD_ON;
  849. if ( deblog || tn_deb || debses )
  850. ckstrncat(tn_msg,
  851. "KERBEROS_V5 CLIENT_TO_SERVER|MUTUAL|ENCRYPT_START_TLS|INI_CRED_FWD_ON ",
  852. TN_MSG_LEN);
  853. i++;
  854. }
  855. #endif /* USE_INI_CRED_FWD */
  856. if ( (tn_auth_how == TN_AUTH_HOW_ANY ||
  857. tn_auth_how == TN_AUTH_HOW_MUTUAL) &&
  858. (tn_auth_enc == TN_AUTH_ENC_ANY ||
  859. tn_auth_enc == TN_AUTH_ENC_TELOPT) ) {
  860. str_request[i++] = AUTHTYPE_KERBEROS_V5;
  861. str_request[i] = AUTH_CLIENT_TO_SERVER | AUTH_HOW_MUTUAL;
  862. str_request[i] |= AUTH_ENCRYPT_START_TLS;
  863. if ( deblog || tn_deb || debses )
  864. ckstrncat(tn_msg,
  865. "KERBEROS_V5 CLIENT_TO_SERVER|MUTUAL|ENCRYPT_START_TLS ",
  866. TN_MSG_LEN);
  867. i++;
  868. }
  869. if ( tn_auth_how == TN_AUTH_HOW_ANY ||
  870. tn_auth_how == TN_AUTH_HOW_ONE_WAY ) {
  871. str_request[i++] = AUTHTYPE_KERBEROS_V5;
  872. str_request[i] = AUTH_CLIENT_TO_SERVER | AUTH_HOW_ONE_WAY;
  873. str_request[i] |= AUTH_ENCRYPT_START_TLS;
  874. if ( deblog || tn_deb || debses )
  875. ckstrncat(tn_msg,
  876. "KERBEROS_V5 CLIENT_TO_SERVER|ONE_WAY|ENCRYPT_START_TLS ",
  877. TN_MSG_LEN);
  878. i++;
  879. }
  880. }
  881. #ifdef CK_ENCRYPTION
  882. else
  883. {
  884. #endif /* CK_ENCRYPTION */
  885. #endif /* CK_SSL */
  886. #ifdef CK_ENCRYPTION
  887. #ifdef USE_INI_CRED_FWD
  888. if ( forward_flag &&
  889. TELOPT_ME_MODE(TELOPT_ENCRYPTION) != TN_NG_RF &&
  890. TELOPT_U_MODE(TELOPT_ENCRYPTION) != TN_NG_RF &&
  891. (tn_auth_how == TN_AUTH_HOW_ANY ||
  892. tn_auth_how == TN_AUTH_HOW_MUTUAL) &&
  893. (tn_auth_enc == TN_AUTH_ENC_ANY ||
  894. tn_auth_enc == TN_AUTH_ENC_TELOPT)
  895. )
  896. {
  897. str_request[i++] = AUTHTYPE_KERBEROS_V5;
  898. str_request[i] = AUTH_CLIENT_TO_SERVER | AUTH_HOW_MUTUAL;
  899. str_request[i] |= AUTH_ENCRYPT_USING_TELOPT;
  900. str_request[i] |= INI_CRED_FWD_ON;
  901. if ( deblog || tn_deb || debses )
  902. ckstrncat(tn_msg,
  903. "KERBEROS_V5 CLIENT_TO_SERVER|MUTUAL|ENCRYPT_USING_TELOPT|INI_CRED_FWD_ON ",
  904. TN_MSG_LEN);
  905. i++;
  906. }
  907. #endif /* USE_INI_CRED_FWD */
  908. if ( TELOPT_ME_MODE(TELOPT_ENCRYPTION) != TN_NG_RF &&
  909. TELOPT_U_MODE(TELOPT_ENCRYPTION) != TN_NG_RF &&
  910. (tn_auth_how == TN_AUTH_HOW_ANY ||
  911. tn_auth_how == TN_AUTH_HOW_MUTUAL) &&
  912. (tn_auth_enc == TN_AUTH_ENC_ANY ||
  913. tn_auth_enc == TN_AUTH_ENC_TELOPT) ) {
  914. str_request[i++] = AUTHTYPE_KERBEROS_V5;
  915. str_request[i] = AUTH_CLIENT_TO_SERVER | AUTH_HOW_MUTUAL;
  916. str_request[i] |= AUTH_ENCRYPT_USING_TELOPT;
  917. if ( deblog || tn_deb || debses )
  918. ckstrncat(tn_msg,
  919. "KERBEROS_V5 CLIENT_TO_SERVER|MUTUAL|ENCRYPT_USING_TELOPT ",
  920. TN_MSG_LEN);
  921. i++;
  922. }
  923. #ifdef CK_SSL
  924. }
  925. #endif /* CK_SSL */
  926. #endif /* CK_ENCRYPTION */
  927. if ( TELOPT_ME_MODE(TELOPT_ENCRYPTION) != TN_NG_MU &&
  928. TELOPT_U_MODE(TELOPT_ENCRYPTION) != TN_NG_MU &&
  929. (tn_auth_enc == TN_AUTH_ENC_ANY ||
  930. tn_auth_enc == TN_AUTH_ENC_NONE)
  931. #ifdef CK_SSL
  932. && !(ck_ssleay_is_installed() &&
  933. (tls_active_flag || ssl_active_flag) &&
  934. tls_is_anon(0))
  935. #endif /* CK_SSL */
  936. )
  937. {
  938. #ifdef CK_ENCRYPTION
  939. /* Can't perform mutual authentication without encryption */
  940. if ( tn_auth_how == TN_AUTH_HOW_ANY ||
  941. tn_auth_how == TN_AUTH_HOW_MUTUAL ) {
  942. str_request[i++] = AUTHTYPE_KERBEROS_V5;
  943. str_request[i] = AUTH_CLIENT_TO_SERVER | AUTH_HOW_MUTUAL;
  944. str_request[i] |= AUTH_ENCRYPT_OFF;
  945. if ( deblog || tn_deb || debses )
  946. ckstrncat(tn_msg,"KERBEROS_V5 CLIENT_TO_SERVER|MUTUAL ",
  947. TN_MSG_LEN);
  948. i++;
  949. }
  950. #endif /* CK_ENCRYPTION */
  951. if ( tn_auth_how == TN_AUTH_HOW_ANY ||
  952. tn_auth_how == TN_AUTH_HOW_ONE_WAY ) {
  953. str_request[i++] = AUTHTYPE_KERBEROS_V5;
  954. str_request[i] = AUTH_CLIENT_TO_SERVER | AUTH_HOW_ONE_WAY;
  955. str_request[i] |= AUTH_ENCRYPT_OFF;
  956. if ( deblog || tn_deb || debses )
  957. ckstrncat(tn_msg,"KERBEROS_V5 CLIENT_TO_SERVER|ONE_WAY ",
  958. TN_MSG_LEN);
  959. i++;
  960. }
  961. }
  962. }
  963. return(i);
  964. }
  965. #endif /* KRB5 */
  966. #ifdef KRB4
  967. static int
  968. ck_tn_auth_request_krb4(int i)
  969. {
  970. if (ck_krb4_is_installed_as_server()) {
  971. #ifdef CK_ENCRYPTION
  972. if (TELOPT_ME_MODE(TELOPT_ENCRYPTION) != TN_NG_RF &&
  973. TELOPT_U_MODE(TELOPT_ENCRYPTION) != TN_NG_RF &&
  974. (tn_auth_how == TN_AUTH_HOW_ANY ||
  975. tn_auth_how == TN_AUTH_HOW_MUTUAL) &&
  976. (tn_auth_enc == TN_AUTH_ENC_ANY ||
  977. tn_auth_enc == TN_AUTH_ENC_TELOPT) )
  978. {
  979. str_request[i++] = AUTHTYPE_KERBEROS_V4;
  980. str_request[i] = AUTH_CLIENT_TO_SERVER | AUTH_HOW_MUTUAL;
  981. str_request[i] |= AUTH_ENCRYPT_USING_TELOPT;
  982. if ( deblog || tn_deb || debses )
  983. ckstrncat(tn_msg,"KERBEROS_V4 CLIENT_TO_SERVER|MUTUAL|ENCRYPT ",
  984. TN_MSG_LEN);
  985. i++;
  986. }
  987. #endif /* CK_ENCRYPTION */
  988. if (TELOPT_ME_MODE(TELOPT_ENCRYPTION) != TN_NG_MU &&
  989. TELOPT_U_MODE(TELOPT_ENCRYPTION) != TN_NG_MU &&
  990. (tn_auth_enc == TN_AUTH_ENC_ANY ||
  991. tn_auth_enc == TN_AUTH_ENC_NONE) )
  992. {
  993. #ifdef CK_ENCRYPTION
  994. /* Can't perform mutual authentication without encryption */
  995. if ( tn_auth_how == TN_AUTH_HOW_ANY ||
  996. tn_auth_how == TN_AUTH_HOW_MUTUAL ) {
  997. str_request[i++] = AUTHTYPE_KERBEROS_V4;
  998. str_request[i] = AUTH_CLIENT_TO_SERVER | AUTH_HOW_MUTUAL;
  999. str_request[i] |= AUTH_ENCRYPT_OFF;
  1000. if ( deblog || tn_deb || debses )
  1001. ckstrncat(tn_msg,"KERBEROS_V4 CLIENT_TO_SERVER|MUTUAL ",
  1002. TN_MSG_LEN);
  1003. i++;
  1004. }
  1005. #endif /* CK_ENCRYPTION */
  1006. if ( tn_auth_how == TN_AUTH_HOW_ANY ||
  1007. tn_auth_how == TN_AUTH_HOW_ONE_WAY ) {
  1008. str_request[i++] = AUTHTYPE_KERBEROS_V4;
  1009. str_request[i] = AUTH_CLIENT_TO_SERVER | AUTH_HOW_ONE_WAY;
  1010. str_request[i] |= AUTH_ENCRYPT_OFF;
  1011. if ( deblog || tn_deb || debses )
  1012. ckstrncat(tn_msg,"KERBEROS_V4 CLIENT_TO_SERVER|ONE_WAY ",
  1013. TN_MSG_LEN);
  1014. i++;
  1015. }
  1016. }
  1017. }
  1018. return(i);
  1019. }
  1020. #endif /* KRB4 */
  1021. #ifdef CK_SRP
  1022. static int
  1023. ck_tn_auth_request_srp(int i)
  1024. {
  1025. if (ck_srp_is_installed_as_server()) {
  1026. #ifndef PRE_SRP_1_4_5
  1027. /* Dont' do this yet. SRP when it uses the ENCRYPT_USING_TELOPT */
  1028. /* flag it must perform a checksum of the auth-type-pair but there */
  1029. /* is no mechansim to do that yet. */
  1030. #ifdef CK_SSL
  1031. if ( ck_ssleay_is_installed() &&
  1032. (tls_active_flag || ssl_active_flag) &&
  1033. ssl_finished_messages &&
  1034. (tn_auth_how == TN_AUTH_HOW_ANY ||
  1035. tn_auth_how == TN_AUTH_HOW_ONE_WAY) &&
  1036. (tn_auth_enc == TN_AUTH_ENC_ANY ||
  1037. tn_auth_enc == TN_AUTH_ENC_TELOPT))
  1038. {
  1039. str_request[i++] = AUTHTYPE_SRP;
  1040. str_request[i] = AUTH_CLIENT_TO_SERVER | AUTH_HOW_ONE_WAY;
  1041. str_request[i] |= AUTH_ENCRYPT_START_TLS;
  1042. if ( deblog || tn_deb || debses )
  1043. ckstrncat(tn_msg,
  1044. "SRP CLIENT_TO_SERVER|ONE_WAY|ENCRYPT_START_TLS ",
  1045. TN_MSG_LEN);
  1046. i++;
  1047. }
  1048. #ifdef CK_ENCRYPTION
  1049. else {
  1050. #endif /* CK_ENCRYPTION */
  1051. #endif /* CK_SSL */
  1052. #ifdef CK_ENCRYPTION
  1053. if (TELOPT_ME_MODE(TELOPT_ENCRYPTION) != TN_NG_RF &&
  1054. TELOPT_U_MODE(TELOPT_ENCRYPTION) != TN_NG_RF &&
  1055. (tn_auth_how == TN_AUTH_HOW_ANY ||
  1056. tn_auth_how == TN_AUTH_HOW_ONE_WAY) &&
  1057. (tn_auth_enc == TN_AUTH_ENC_ANY ||
  1058. tn_auth_enc == TN_AUTH_ENC_TELOPT)
  1059. ) {
  1060. str_request[i++] = AUTHTYPE_SRP;
  1061. str_request[i] = AUTH_CLIENT_TO_SERVER | AUTH_HOW_ONE_WAY;
  1062. str_request[i] |= AUTH_ENCRYPT_USING_TELOPT;
  1063. if ( deblog || tn_deb || debses )
  1064. ckstrncat(tn_msg,
  1065. "SRP CLIENT_TO_SERVER|ONE_WAY|ENCRYPT_USING_TELOPT ",
  1066. TN_MSG_LEN);
  1067. i++;
  1068. }
  1069. #ifdef CK_SSL
  1070. }
  1071. #endif /* CK_SSL */
  1072. #endif /* CK_ENCRYPTION */
  1073. #endif /* PRE_SRP_1_4_5 */
  1074. if (TELOPT_ME_MODE(TELOPT_ENCRYPTION) != TN_NG_MU &&
  1075. TELOPT_U_MODE(TELOPT_ENCRYPTION) != TN_NG_MU &&
  1076. (tn_auth_how == TN_AUTH_HOW_ANY ||
  1077. tn_auth_how == TN_AUTH_HOW_MUTUAL) &&
  1078. (tn_auth_enc == TN_AUTH_ENC_ANY ||
  1079. tn_auth_enc == TN_AUTH_ENC_NONE)
  1080. #ifdef CK_SSL
  1081. && !(ck_ssleay_is_installed() &&
  1082. (tls_active_flag || ssl_active_flag) &&
  1083. tls_is_anon(0))
  1084. #endif /* CK_SSL */
  1085. )
  1086. {
  1087. str_request[i++] = AUTHTYPE_SRP;
  1088. str_request[i] = AUTH_CLIENT_TO_SERVER | AUTH_HOW_ONE_WAY;
  1089. str_request[i] |= AUTH_ENCRYPT_OFF;
  1090. if ( deblog || tn_deb || debses )
  1091. ckstrncat(tn_msg,"SRP CLIENT_TO_SERVER|ONE_WAY ",
  1092. TN_MSG_LEN);
  1093. i++;
  1094. }
  1095. }
  1096. return(i);
  1097. }
  1098. #endif /* CK_SRP */
  1099. #ifdef CK_SSL
  1100. static int
  1101. ck_tn_auth_request_ssl(int i)
  1102. {
  1103. if (ck_ssleay_is_installed()
  1104. && !tls_active_flag && !ssl_active_flag && ssl_initialized
  1105. ) {
  1106. if (TELOPT_ME_MODE(TELOPT_ENCRYPTION) != TN_NG_MU &&
  1107. TELOPT_U_MODE(TELOPT_ENCRYPTION) != TN_NG_MU &&
  1108. (tn_auth_how == TN_AUTH_HOW_ANY ||
  1109. tn_auth_how == TN_AUTH_HOW_ONE_WAY) &&
  1110. (tn_auth_enc == TN_AUTH_ENC_ANY ||
  1111. tn_auth_enc == TN_AUTH_ENC_NONE) )
  1112. {
  1113. str_request[i++] = AUTHTYPE_SSL;
  1114. str_request[i] = AUTH_CLIENT_TO_SERVER | AUTH_HOW_ONE_WAY;
  1115. str_request[i] |= AUTH_ENCRYPT_OFF;
  1116. if ( deblog || tn_deb || debses )
  1117. ckstrncat(tn_msg,"SSL CLIENT_TO_SERVER|ONE_WAY ",
  1118. TN_MSG_LEN);
  1119. i++;
  1120. }
  1121. }
  1122. return(i);
  1123. }
  1124. #endif /* CK_SSL */
  1125. #ifdef NTLM
  1126. static int
  1127. ck_tn_auth_request_ntlm(int i)
  1128. {
  1129. /* Microsoft's Telnet client won't perform authentication if */
  1130. /* NTLM is not first. */
  1131. if ( ck_ntlm_is_valid(1) ) {
  1132. if (TELOPT_ME_MODE(TELOPT_ENCRYPTION) != TN_NG_MU &&
  1133. TELOPT_U_MODE(TELOPT_ENCRYPTION) != TN_NG_MU &&
  1134. (tn_auth_how == TN_AUTH_HOW_ANY ||
  1135. tn_auth_how == TN_AUTH_HOW_ONE_WAY) &&
  1136. (tn_auth_enc == TN_AUTH_ENC_ANY ||
  1137. tn_auth_enc == TN_AUTH_ENC_NONE) )
  1138. {
  1139. str_request[i++] = AUTHTYPE_NTLM;
  1140. str_request[i] = AUTH_CLIENT_TO_SERVER | AUTH_HOW_ONE_WAY;
  1141. str_request[i] |= AUTH_ENCRYPT_OFF;
  1142. if ( deblog || tn_deb || debses )
  1143. ckstrncat(tn_msg,"NTLM CLIENT_TO_SERVER|ONE_WAY ",
  1144. TN_MSG_LEN);
  1145. i++;
  1146. }
  1147. }
  1148. return(i);
  1149. }
  1150. #endif /* NTLM */
  1151. int
  1152. #ifdef CK_ANSIC
  1153. ck_tn_auth_request(void)
  1154. #else
  1155. ck_tn_auth_request()
  1156. #endif
  1157. {
  1158. int i = 4, rc = -1;
  1159. #ifdef CK_SSL
  1160. if (TELOPT_SB(TELOPT_START_TLS).start_tls.me_follows) {
  1161. return(0);
  1162. }
  1163. #endif /* CK_SSL */
  1164. if ( deblog || tn_deb || debses )
  1165. strcpy(tn_msg,"TELNET SENT SB AUTHENTICATION SEND ");
  1166. /* Create a list of acceptable Authentication types to send to */
  1167. /* the client and let it choose find one that we support */
  1168. /* For those authentication methods that support Encryption or */
  1169. /* Credentials Forwarding we must send all of the appropriate */
  1170. /* combinations based upon the state of */
  1171. /* TELOPT_x_MODE(TELOPT_ENCRYPTION) and forward_flag. */
  1172. if ( auth_type_user[0] == AUTHTYPE_AUTO ) {
  1173. #ifdef GSSAPI_K5
  1174. i = ck_tn_auth_request_gsskrb5(i);
  1175. #endif /* GSSAPI_K5 */
  1176. #ifdef KRB5
  1177. i = ck_tn_auth_request_krb5(i);
  1178. #endif /* KRB5 */
  1179. #ifdef KRB4
  1180. i = ck_tn_auth_request_krb4(i);
  1181. #endif /* KRB4 */
  1182. #ifdef CK_SRP
  1183. i = ck_tn_auth_request_srp(i);
  1184. #endif /* SRP */
  1185. #ifdef CK_SSL
  1186. i = ck_tn_auth_request_ssl(i);
  1187. #endif /* CK_SSL */
  1188. #ifdef NTLM
  1189. i = ck_tn_auth_request_ntlm(i);
  1190. #endif /* NTLM */
  1191. } else {
  1192. int j;
  1193. for ( j=0;
  1194. j<AUTHTYPLSTSZ && auth_type_user[j] != AUTHTYPE_NULL;
  1195. j++) {
  1196. #ifdef NTLM
  1197. if (auth_type_user[j] == AUTHTYPE_NTLM)
  1198. i = ck_tn_auth_request_ntlm(i);
  1199. #endif /* NTLM */
  1200. #ifdef CK_SSL
  1201. if ( auth_type_user[j] == AUTHTYPE_SSL )
  1202. i = ck_tn_auth_request_ssl(i);
  1203. #endif /* CK_SSL */
  1204. #ifdef CK_SRP
  1205. if ( auth_type_user[j] == AUTHTYPE_SRP )
  1206. i = ck_tn_auth_request_srp(i);
  1207. #endif /* SRP */
  1208. #ifdef GSSAPI_K5
  1209. if ( auth_type_user[j] == AUTHTYPE_GSSAPI_KRB5 )
  1210. i = ck_tn_auth_request_gsskrb5(i);
  1211. #endif /* GSSAPI_K5 */
  1212. #ifdef KRB5
  1213. if ( auth_type_user[j] == AUTHTYPE_KERBEROS_V5 )
  1214. i = ck_tn_auth_request_krb5(i);
  1215. #endif /* KRB5 */
  1216. #ifdef KRB4
  1217. if ( auth_type_user[j] == AUTHTYPE_KERBEROS_V4 )
  1218. i = ck_tn_auth_request_krb4(i);
  1219. #endif /* KRB4 */
  1220. }
  1221. }
  1222. str_request[i++] = IAC;
  1223. str_request[i++] = SE;
  1224. if ( deblog || tn_deb || debses ) {
  1225. ckstrncat(tn_msg,"IAC SE",TN_MSG_LEN);
  1226. debug(F100,tn_msg,"",0);
  1227. if (tn_deb || debses) tn_debug(tn_msg);
  1228. }
  1229. /* Send data */
  1230. #ifdef OS2
  1231. RequestTelnetMutex( SEM_INDEFINITE_WAIT );
  1232. #endif
  1233. rc = ttol((CHAR *)str_request, i);
  1234. #ifdef OS2
  1235. ReleaseTelnetMutex();
  1236. #endif
  1237. if ( rc == i )
  1238. return(0);
  1239. else
  1240. return(-1);
  1241. }
  1242. #ifdef CK_ENCRYPTION
  1243. VOID
  1244. ck_tn_enc_start()
  1245. {
  1246. if (!TELOPT_ME(TELOPT_ENCRYPTION) && !TELOPT_U(TELOPT_ENCRYPTION))
  1247. return;
  1248. if (!TELOPT_SB(TELOPT_ENCRYPTION).encrypt.stop &&
  1249. (!encrypt_is_decrypting() || !encrypt_is_encrypting())) {
  1250. debug(F110,"ck_tn_enc_start","nothing to do",0);
  1251. return;
  1252. }
  1253. TELOPT_SB(TELOPT_ENCRYPTION).encrypt.stop = 0;
  1254. if (TELOPT_ME(TELOPT_ENCRYPTION) && !encrypt_is_encrypting()) {
  1255. debug(F110,"ck_tn_enc_start","encrypt_request_start",0);
  1256. encrypt_request_start();
  1257. }
  1258. if (TELOPT_U(TELOPT_ENCRYPTION) && !encrypt_is_decrypting()) {
  1259. debug(F110,"ck_tn_enc_start","encrypt_send_request_start",0);
  1260. encrypt_send_request_start();
  1261. }
  1262. tn_wait("encrypt start");
  1263. tn_push();
  1264. }
  1265. VOID
  1266. ck_tn_enc_stop()
  1267. {
  1268. if (!TELOPT_ME(TELOPT_ENCRYPTION) && !TELOPT_U(TELOPT_ENCRYPTION))
  1269. return;
  1270. if (TELOPT_SB(TELOPT_ENCRYPTION).encrypt.stop ||
  1271. !(encrypt_is_decrypting() || encrypt_is_encrypting())) {
  1272. debug(F110,"ck_tn_enc_stop","nothing to do",0);
  1273. return;
  1274. }
  1275. TELOPT_SB(TELOPT_ENCRYPTION).encrypt.stop = 1;
  1276. if (TELOPT_U(TELOPT_ENCRYPTION) && encrypt_is_decrypting()) {
  1277. debug(F110,"ck_tn_enc_stop","encrypt_send_request_end",0);
  1278. encrypt_send_request_end();
  1279. }
  1280. if (TELOPT_ME(TELOPT_ENCRYPTION) && encrypt_is_encrypting()) {
  1281. debug(F110,"ck_tn_enc_stop","encrypt_send_end",0);
  1282. encrypt_send_end();
  1283. }
  1284. tn_wait("encrypt stop");
  1285. tn_push();
  1286. }
  1287. #endif /* CK_ENCRYPTION */
  1288. /* C K _ K R B _ T N _ S B _ A U T H
  1289. * An interface between the C-Kermit Telnet Command Parser and the Authent-
  1290. * ication option parser implemented in the Kerberos Telnet client.
  1291. *
  1292. * sb - the subnegotiation as calculated in ckcnet.c
  1293. * len - the length of the buffer
  1294. *
  1295. * Returns: 0 on success and -1 on failure
  1296. */
  1297. int
  1298. #ifdef CK_ANSIC
  1299. ck_tn_sb_auth(char * sb, int len)
  1300. #else /* CK_ANSIC */
  1301. ck_tn_sb_auth(sb,len) char * sb; int len;
  1302. #endif /* CK_ANSIC */
  1303. {
  1304. /* auth_parse() assumes that sb starts at pos 1 not 0 as in ckcnet.c */
  1305. /* and it wants the length to exclude the IAC SE bytes */
  1306. CHAR * buf;
  1307. int rc = -1;
  1308. buf = malloc(len-1);
  1309. if ( !buf ) return(-1);
  1310. buf[0] = SB;
  1311. memcpy( &buf[1], sb, len-2 );
  1312. rc = auth_parse(buf,len-1);
  1313. free(buf);
  1314. debug(F111,"ck_tn_sb_auth","rc",rc);
  1315. if (rc == AUTH_FAILURE) {
  1316. authentication_version = AUTHTYPE_NULL;
  1317. #ifndef NOLOCAL
  1318. #ifdef OS2
  1319. ipadl25();
  1320. #endif /* OS2 */
  1321. #endif /* NOLOCAL */
  1322. return(-1);
  1323. }
  1324. #ifndef NOLOCAL
  1325. #ifdef OS2
  1326. ipadl25();
  1327. #endif /* OS2 */
  1328. #endif /* NOLOCAL */
  1329. return(0);
  1330. }
  1331. /* C K _ K R B _ T N _ S B _ E N C R Y P T
  1332. * An interface between the C-Kermit Telnet Command Parser and the Encryption
  1333. * option parser implemented in the Kerberos Telnet client.
  1334. *
  1335. * sb - the subnegotiation as calculated in ckcnet.c
  1336. * len - the length of the buffer
  1337. *
  1338. * Returns: Always returns 0 for success since encrypt_parse is void
  1339. */
  1340. int
  1341. #ifdef CK_ANSIC
  1342. ck_tn_sb_encrypt(char * sb, int len)
  1343. #else
  1344. ck_tn_sb_encrypt(sb,len) char * sb; int len;
  1345. #endif /* CK_ANSIC */
  1346. {
  1347. /* encrypt_parse() assumes that sb starts at pos 1 not 0 as in ckcnet.c */
  1348. /* and it wants the length to exclude the IAC SE bytes */
  1349. #ifdef CK_ENCRYPTION
  1350. char * buf;
  1351. int rc = -1;
  1352. buf = malloc(len-1);
  1353. if ( !buf ) return(-1);
  1354. buf[0] = SB;
  1355. memcpy( &buf[1], sb, len-2 );
  1356. rc = encrypt_parse((CHAR *)buf,len-1);
  1357. if (rc < 0) {
  1358. free(buf);
  1359. return(-1);
  1360. }
  1361. /* This is a hack. It does not belong here but should really be in */
  1362. /* encrypt_parse() but in K95 the encrypt_parse() routine does not */
  1363. /* have access to the telopt_states array. */
  1364. if ( buf[1] == ENCRYPT_REQEND )
  1365. TELOPT_SB(TELOPT_ENCRYPTION).encrypt.stop = 1;
  1366. else if ( buf[1] == ENCRYPT_REQSTART )
  1367. TELOPT_SB(TELOPT_ENCRYPTION).encrypt.stop = 0;
  1368. #ifndef NOLOCAL
  1369. #ifdef OS2
  1370. ipadl25();
  1371. #endif /* OS2 */
  1372. #endif /* NOLOCAL */
  1373. free(buf);
  1374. #endif /* ENCRYPTION */
  1375. return(0);
  1376. }
  1377. /* C K _ K R B _ E N C R Y P T I N G
  1378. * Returns 1 if we are encrypting and 0 if we are not
  1379. */
  1380. int
  1381. #ifdef CK_ANSIC
  1382. ck_tn_encrypting(VOID)
  1383. #else /* CK_ANSIC */
  1384. ck_tn_encrypting()
  1385. #endif /* CK_ANSIC */
  1386. {
  1387. #ifdef CK_ENCRYPTION
  1388. if ( g_kstream == NULL )
  1389. return(0);
  1390. if ( g_kstream->encrypt && encrypt_is_encrypting()) {
  1391. debug(F111,"ck_tn_encrypting","encrypting",
  1392. g_kstream->encrypt_type);
  1393. return(g_kstream->encrypt_type);
  1394. }
  1395. #endif /* CK_ENCRYPTION */
  1396. debug(F110,"ck_tn_encrypting","not encrypting",0);
  1397. return(0);
  1398. }
  1399. /* C K _ K R B _ D E C R Y P T I N G
  1400. * Returns 1 if we are decrypting and 0 if we are not
  1401. */
  1402. int
  1403. #ifdef CK_ANSIC
  1404. ck_tn_decrypting(VOID)
  1405. #else
  1406. ck_tn_decrypting()
  1407. #endif /* CK_ANSIC */
  1408. {
  1409. #ifdef CK_ENCRYPTION
  1410. if ( g_kstream == NULL )
  1411. return(0);
  1412. if ( g_kstream->decrypt && encrypt_is_decrypting()) {
  1413. debug(F111,"ck_tn_decrypting","decrypting",
  1414. g_kstream->decrypt_type);
  1415. return(g_kstream->decrypt_type);
  1416. }
  1417. #endif /* CK_ENCRYPTION */
  1418. debug(F110,"ck_tn_decrypting","not decrypting",0);
  1419. return(0);
  1420. }
  1421. /* C K _ K R B _ A U T H E N T I C A T E D
  1422. * Returns the authentication type: AUTHTYPE_NULL, AUTHTYPE_KERBEROS4,
  1423. * or AUTHTYPE_KERBEROS5, AUTHTYPE_SRP, ... (see ckctel.h)
  1424. */
  1425. int
  1426. #ifdef CK_ANSIC
  1427. ck_tn_authenticated(VOID)
  1428. #else
  1429. ck_tn_authenticated()
  1430. #endif
  1431. {
  1432. return(authentication_version);
  1433. }
  1434. /* C K _ K R B _ E N C R Y P T
  1435. * encrypts n characters in s if we are encrypting
  1436. */
  1437. VOID
  1438. #ifdef CK_ANSIC
  1439. ck_tn_encrypt( char * s, int n )
  1440. #else
  1441. ck_tn_encrypt( s,n ) char * s; int n;
  1442. #endif
  1443. {
  1444. #ifdef CK_ENCRYPTION
  1445. struct kstream_data_block i;
  1446. if (g_kstream->encrypt && encrypt_is_encrypting()) {
  1447. #ifdef DEBUG
  1448. ckhexdump("from plaintext", s, n);
  1449. #endif
  1450. i.ptr = s;
  1451. i.length = n;
  1452. g_kstream->encrypt(&i, NULL);
  1453. #ifdef DEBUG
  1454. ckhexdump("to cyphertext", s, n);
  1455. #endif
  1456. }
  1457. else debug(F101,"ck_tn_encrypt not encrypting","",n);
  1458. #endif /* ENCRYPTION */
  1459. }
  1460. /* C K _ K R B _ D E C R Y P T
  1461. * decrypts n characters in s if we are decrypting
  1462. */
  1463. VOID
  1464. #ifdef CK_ANSIC
  1465. ck_tn_decrypt( char * s, int n )
  1466. #else
  1467. ck_tn_decrypt( s,n ) char * s; int n;
  1468. #endif
  1469. {
  1470. #ifdef CK_ENCRYPTION
  1471. struct kstream_data_block i;
  1472. if (g_kstream->decrypt && encrypt_is_decrypting()) {
  1473. #ifdef DEBUG
  1474. ckhexdump("from cyphertext", s, n);
  1475. #endif
  1476. i.ptr = s;
  1477. i.length = n;
  1478. g_kstream->decrypt(&i, NULL);
  1479. #ifdef DEBUG
  1480. ckhexdump("to plaintext", s, n);
  1481. #endif
  1482. }
  1483. else debug(F101,"ck_tn_decrypt not decrypting","",n);
  1484. #endif /* ENCRYPTION */
  1485. }
  1486. /* S E N D K 5 A U T H S B
  1487. * Send a Kerberos 5 Authentication Subnegotiation to host and
  1488. * output appropriate Telnet Debug messages
  1489. *
  1490. * type - Sub Negotiation type
  1491. * data - ptr to buffer containing data
  1492. * len - len of buffer if not NUL terminated
  1493. *
  1494. * returns number of characters sent or error value
  1495. */
  1496. static int
  1497. #ifdef CK_ANSIC
  1498. SendK5AuthSB(int type, void *data, int len)
  1499. #else
  1500. SendK5AuthSB(type,data,len) int type; void *data; int len;
  1501. #endif
  1502. {
  1503. int rc;
  1504. unsigned char *p = str_data + 3;
  1505. unsigned char *cd = (unsigned char *)data;
  1506. extern int sstelnet;
  1507. #ifdef CK_SSL
  1508. if (TELOPT_SB(TELOPT_START_TLS).start_tls.me_follows) {
  1509. if (ttchk() < 0)
  1510. return(0);
  1511. else
  1512. return(1);
  1513. }
  1514. #endif /* CK_SSL */
  1515. if ( type < 0 || type > 7 ) /* Check for invalid values */
  1516. return(0);
  1517. if (!cd) {
  1518. cd = (unsigned char *)"";
  1519. len = 0;
  1520. }
  1521. if (len == -1) /* Use strlen() for len */
  1522. len = strlen((char *)cd);
  1523. /* Construct Message */
  1524. *p++ = sstelnet ? TELQUAL_REPLY : TELQUAL_IS;
  1525. *p++ = AUTHTYPE_KERBEROS_V5;
  1526. *p = AUTH_CLIENT_TO_SERVER;
  1527. *p |= auth_how;
  1528. #ifdef CK_ENCRYPTION
  1529. *p |= auth_crypt;
  1530. #endif
  1531. #ifdef USE_INI_CRED_FWD
  1532. if (auth_fwd)
  1533. *p |= INI_CRED_FWD_ON;
  1534. #endif /* USE_INI_CRED_FWD */
  1535. p++;
  1536. *p++ = type;
  1537. while (len-- > 0) {
  1538. if ((*p++ = *cd++) == IAC)
  1539. *p++ = IAC;
  1540. }
  1541. *p++ = IAC;
  1542. *p++ = SE;
  1543. /* Handle Telnet Debugging Messages */
  1544. if (deblog || tn_deb || debses) {
  1545. int i;
  1546. int deblen=p-str_data-2;
  1547. char *s=NULL;
  1548. int mode = AUTH_CLIENT_TO_SERVER | (auth_how & AUTH_HOW_MASK) |
  1549. auth_crypt
  1550. #ifdef USE_INI_CRED_FWD
  1551. | (auth_fwd?INI_CRED_FWD_ON:INI_CRED_FWD_OFF)
  1552. #endif /* USE_INI_CRED_FWD */
  1553. ;
  1554. switch (type) {
  1555. case 0:
  1556. s = "AUTH";
  1557. break;
  1558. case 1:
  1559. s = "REJECT";
  1560. break;
  1561. case 2:
  1562. s = "ACCEPT";
  1563. break;
  1564. case 3:
  1565. s = "RESPONSE";
  1566. break;
  1567. case 4:
  1568. s = "FORWARD";
  1569. break;
  1570. case 5:
  1571. s = "FORWARD_ACCEPT";
  1572. break;
  1573. case 6:
  1574. s = "FORWARD_REJECT";
  1575. break;
  1576. case 7:
  1577. s = "TLS_VERIFY";
  1578. break;
  1579. }
  1580. ckmakxmsg(tn_msg,TN_MSG_LEN,
  1581. "TELNET SENT SB ",
  1582. TELOPT(TELOPT_AUTHENTICATION)," ",
  1583. str_data[3] == TELQUAL_IS ? "IS" :
  1584. str_data[3] == TELQUAL_REPLY ? "REPLY" : "???"," ",
  1585. AUTHTYPE_NAME(authentication_version)," ",
  1586. AUTHMODE_NAME(mode)," ",
  1587. s," ",NULL);
  1588. tn_hex((CHAR *)tn_msg,TN_MSG_LEN,&str_data[7],deblen-7);
  1589. ckstrncat(tn_msg,"IAC SE",TN_MSG_LEN);
  1590. debug(F100,tn_msg,"",0);
  1591. if (tn_deb || debses) tn_debug(tn_msg);
  1592. }
  1593. /* Send data */
  1594. #ifdef OS2
  1595. RequestTelnetMutex( SEM_INDEFINITE_WAIT );
  1596. #endif
  1597. rc = ttol((CHAR *)str_data, p - str_data);
  1598. #ifdef OS2
  1599. ReleaseTelnetMutex();
  1600. #endif
  1601. debug(F111,"SendK5AuthSB","ttol()",rc);
  1602. return(rc);
  1603. }
  1604. /* S E N D K 4 A U T H S B
  1605. * Send a Kerberos 4 Authentication Subnegotiation to host and
  1606. * output appropriate Telnet Debug messages
  1607. *
  1608. * type - Sub Negotiation type
  1609. * data - ptr to buffer containing data
  1610. * len - len of buffer if not NUL terminated
  1611. *
  1612. * returns number of characters sent or error value
  1613. */
  1614. static int
  1615. #ifdef CK_ANSIC
  1616. SendK4AuthSB(int type, void *data, int len)
  1617. #else
  1618. SendK4AuthSB(type,data,len) int type; void *data; int len;
  1619. #endif
  1620. {
  1621. int rc;
  1622. unsigned char *p = str_data + 3;
  1623. unsigned char *cd = (unsigned char *)data;
  1624. extern int sstelnet;
  1625. int mode = (auth_how & AUTH_HOW_MASK) |
  1626. auth_crypt;
  1627. if ( type < 0 || type > 4 ) /* Check for invalid values */
  1628. return(0);
  1629. #ifdef CK_SSL
  1630. if (TELOPT_SB(TELOPT_START_TLS).start_tls.me_follows) {
  1631. if (ttchk() < 0)
  1632. return(0);
  1633. else
  1634. return(1);
  1635. }
  1636. #endif /* CK_SSL */
  1637. if (!cd) {
  1638. cd = (unsigned char *)"";
  1639. len = 0;
  1640. }
  1641. if (len == -1) /* Use strlen() for len */
  1642. len = strlen((char *)cd);
  1643. /* Construct Message */
  1644. *p++ = sstelnet ? TELQUAL_REPLY : TELQUAL_IS;
  1645. *p++ = AUTHTYPE_KERBEROS_V4;
  1646. *p = AUTH_CLIENT_TO_SERVER;
  1647. *p |= mode;
  1648. p++;
  1649. *p++ = type;
  1650. while (len-- > 0) {
  1651. if ((*p++ = *cd++) == IAC)
  1652. *p++ = IAC;
  1653. }
  1654. *p++ = IAC;
  1655. *p++ = SE;
  1656. /* Handle Telnet Debugging Messages */
  1657. if (deblog || tn_deb || debses) {
  1658. int i;
  1659. int deblen=p-str_data-2;
  1660. char *s=NULL;
  1661. switch (type) {
  1662. case 0:
  1663. s = "AUTH";
  1664. break;
  1665. case 1:
  1666. s = "REJECT";
  1667. break;
  1668. case 2:
  1669. s = "ACCEPT";
  1670. break;
  1671. case 3:
  1672. s = "CHALLENGE";
  1673. break;
  1674. case 4:
  1675. s = "RESPONSE";
  1676. break;
  1677. }
  1678. ckmakxmsg(tn_msg,TN_MSG_LEN,"TELNET SENT SB ",
  1679. TELOPT(TELOPT_AUTHENTICATION)," ",
  1680. str_data[3] == TELQUAL_IS ? "IS" :
  1681. (str_data[3] == TELQUAL_REPLY ? "REPLY" : "???")," ",
  1682. AUTHTYPE_NAME(authentication_version)," ",
  1683. AUTHMODE_NAME(mode)," ",
  1684. s," ",NULL);
  1685. tn_hex((CHAR *)tn_msg,TN_MSG_LEN,&str_data[7],deblen-7);
  1686. ckstrncat(tn_msg,"IAC SE",TN_MSG_LEN);
  1687. debug(F100,tn_msg,"",0);
  1688. if (tn_deb || debses) tn_debug(tn_msg);
  1689. }
  1690. /* Send data */
  1691. #ifdef OS2
  1692. RequestTelnetMutex( SEM_INDEFINITE_WAIT );
  1693. #endif
  1694. rc = ttol((CHAR *)str_data, p - str_data);
  1695. #ifdef OS2
  1696. ReleaseTelnetMutex();
  1697. #endif
  1698. debug(F111,"SendK4AuthSB","ttol()",rc);
  1699. return(rc);
  1700. }
  1701. /* S E N D S R P A U T H S B
  1702. * Send a SRP Authentication Subnegotiation to host and
  1703. * output appropriate Telnet Debug messages
  1704. *
  1705. * type - Sub Negotiation type
  1706. * data - ptr to buffer containing data
  1707. * len - len of buffer if not NUL terminated
  1708. *
  1709. * returns number of characters sent or error value
  1710. */
  1711. static int
  1712. #ifdef CK_ANSIC
  1713. SendSRPAuthSB(int type, void *data, int len)
  1714. #else
  1715. SendSRPAuthSB(type,data,len) int type; void *data; int len;
  1716. #endif
  1717. {
  1718. int rc;
  1719. unsigned char *p = str_data + 3;
  1720. unsigned char *cd = (unsigned char *)data;
  1721. extern int sstelnet;
  1722. /* Check for invalid values */
  1723. if ( type != SRP_EXP && type != SRP_RESPONSE &&
  1724. type != SRP_REJECT && type != SRP_ACCEPT &&
  1725. type != SRP_CHALLENGE && type != SRP_PARAMS &&
  1726. type != SRP_AUTH)
  1727. return(0);
  1728. if (len == -1) /* Use strlen() for len */
  1729. len = strlen((char *)cd);
  1730. /* Construct Message */
  1731. *p++ = sstelnet ? TELQUAL_REPLY : TELQUAL_IS;
  1732. *p++ = AUTHTYPE_SRP;
  1733. *p = AUTH_CLIENT_TO_SERVER;
  1734. *p |= auth_how;
  1735. #ifdef CK_ENCRYPTION
  1736. *p |= auth_crypt;
  1737. #endif
  1738. p++;
  1739. *p++ = type;
  1740. while (len-- > 0) {
  1741. if ((*p++ = *cd++) == IAC)
  1742. *p++ = IAC;
  1743. }
  1744. *p++ = IAC;
  1745. *p++ = SE;
  1746. /* Handle Telnet Debugging Messages */
  1747. if (deblog || tn_deb || debses) {
  1748. int i;
  1749. int deblen=p-str_data-2;
  1750. char *s=NULL;
  1751. int mode = AUTH_CLIENT_TO_SERVER | (auth_how & AUTH_HOW_MASK) |
  1752. auth_crypt;
  1753. switch (type) {
  1754. case 0:
  1755. s = "AUTH";
  1756. break;
  1757. case 1:
  1758. s = "REJECT";
  1759. break;
  1760. case 2:
  1761. s = "ACCEPT";
  1762. break;
  1763. case 3:
  1764. s = "CHALLENGE";
  1765. break;
  1766. case 4:
  1767. s = "RESPONSE";
  1768. break;
  1769. case 5:
  1770. s = "FORWARD";
  1771. break;
  1772. case 6:
  1773. s = "FORWARD_ACCEPT";
  1774. break;
  1775. case 7:
  1776. s = "FORWARD_REJECT";
  1777. break;
  1778. case 8:
  1779. s = "EXP";
  1780. break;
  1781. case 9:
  1782. s = "PARAMS";
  1783. break;
  1784. }
  1785. ckmakxmsg(tn_msg,TN_MSG_LEN,
  1786. "TELNET SENT SB ",
  1787. TELOPT(TELOPT_AUTHENTICATION)," ",
  1788. str_data[3] == TELQUAL_REPLY ? "REPLY" :
  1789. str_data[3] == TELQUAL_IS ? "IS" : "???"," ",
  1790. AUTHTYPE_NAME(authentication_version)," ",
  1791. AUTHMODE_NAME(mode)," ",
  1792. s," ",NULL);
  1793. tn_hex((CHAR *)tn_msg,TN_MSG_LEN,&str_data[7],deblen-7);
  1794. ckstrncat(tn_msg,"IAC SE",TN_MSG_LEN);
  1795. debug(F100,tn_msg,"",0);
  1796. if (tn_deb || debses) tn_debug(tn_msg);
  1797. }
  1798. /* Send data */
  1799. #ifdef OS2
  1800. RequestTelnetMutex( SEM_INDEFINITE_WAIT );
  1801. #endif
  1802. rc = ttol((CHAR *)str_data, p - str_data);
  1803. #ifdef OS2
  1804. ReleaseTelnetMutex();
  1805. #endif
  1806. return(rc);
  1807. }
  1808. #ifdef CK_ENCRYPTION
  1809. /*
  1810. * Function: Enable or disable the encryption process.
  1811. *
  1812. * Parameters:
  1813. * enable - TRUE to enable, FALSE to disable.
  1814. */
  1815. static VOID
  1816. #ifdef CK_ANSIC
  1817. auth_encrypt_enable(BOOL enable)
  1818. #else
  1819. auth_encrypt_enable(enable) BOOL enable;
  1820. #endif
  1821. {
  1822. encrypt_flag = enable;
  1823. }
  1824. #endif
  1825. /*
  1826. * Function: Abort the authentication process
  1827. *
  1828. * Parameters:
  1829. */
  1830. static VOID
  1831. #ifdef CK_ANSIC
  1832. auth_abort(char *errmsg, long r)
  1833. #else
  1834. auth_abort(errmsg,r) char *errmsg; long r;
  1835. #endif
  1836. {
  1837. char buf[9];
  1838. extern int sstelnet;
  1839. #ifdef CK_SSL
  1840. if (TELOPT_SB(TELOPT_START_TLS).start_tls.me_follows) {
  1841. return;
  1842. }
  1843. #endif /* CK_SSL */
  1844. debug(F111,"auth_abort",errmsg,r);
  1845. /* Construct Telnet Debugging messages */
  1846. if (deblog || tn_deb || debses) {
  1847. ckmakxmsg(tn_msg,TN_MSG_LEN,
  1848. "TELNET SENT SB ",TELOPT(TELOPT_AUTHENTICATION),
  1849. " IS ",AUTHTYPE_NAME(AUTHTYPE_NULL)," ",
  1850. AUTHTYPE_NAME(AUTHTYPE_NULL)," IAC SE",
  1851. NULL,NULL,NULL,NULL,NULL
  1852. );
  1853. debug(F100,tn_msg,"",0);
  1854. if (tn_deb || debses) tn_debug(tn_msg);
  1855. }
  1856. /* Construct the Abort message to send to the host */
  1857. /* Basicly we change the authentication type to NULL */
  1858. sprintf(buf, "%c%c%c%c%c%c%c%c", IAC, SB, TELOPT_AUTHENTICATION,
  1859. sstelnet ? TELQUAL_REPLY : TELQUAL_IS, AUTHTYPE_NULL,
  1860. AUTHTYPE_NULL, IAC, SE); /* safe */
  1861. #ifdef OS2
  1862. RequestTelnetMutex( SEM_INDEFINITE_WAIT );
  1863. #endif
  1864. ttol((CHAR *)buf, 8);
  1865. #ifdef OS2
  1866. ReleaseTelnetMutex();
  1867. #endif
  1868. /* If there is an error message, and error number construct */
  1869. /* an explanation to display to the user */
  1870. if (errmsg != NULL) {
  1871. ckstrncpy(strTmp, errmsg, AUTHTMPBL);
  1872. } else
  1873. strTmp[0] = '\0';
  1874. if (r != AUTH_SUCCESS) {
  1875. ckstrncat(strTmp, "\r\n",AUTHTMPBL);
  1876. #ifdef KRB4
  1877. if ( authentication_version == AUTHTYPE_KERBEROS_V4 ) {
  1878. ckstrncat(strTmp, (char *)krb_get_err_text_entry(r),
  1879. AUTHTMPBL);
  1880. debug(F111,"auth_abort",(char *)krb_get_err_text_entry(r),r);
  1881. }
  1882. #endif
  1883. #ifdef KRB5
  1884. if ( authentication_version == AUTHTYPE_KERBEROS_V5 ) {
  1885. ckstrncat(strTmp, error_message(r),AUTHTMPBL);
  1886. debug(F111,"auth_abort",error_message(r),r);
  1887. }
  1888. #endif
  1889. }
  1890. printf("Authentication failed: %s\r\n",strTmp);
  1891. #ifdef CKSYSLOG
  1892. if (ckxsyslog >= SYSLG_LI && ckxlogging) {
  1893. cksyslog(SYSLG_LI, 0, "Telnet authentication failure",
  1894. (char *) szUserNameRequested,
  1895. strTmp);
  1896. }
  1897. #endif /* CKSYSLOG */
  1898. authentication_version = AUTHTYPE_NULL;
  1899. }
  1900. /*
  1901. * Function: Copy data to buffer, doubling IAC character if present.
  1902. *
  1903. */
  1904. int
  1905. #ifdef CK_ANSIC
  1906. copy_for_net(unsigned char *to, unsigned char *from, int c)
  1907. #else
  1908. copy_for_net(to,from,c) unsigned char *to; unsigned char *from; int c;
  1909. #endif
  1910. {
  1911. int n;
  1912. n = c;
  1913. debug(F111,"copy_for_net","before",n);
  1914. while (c-- > 0) {
  1915. if ((*to++ = *from++) == IAC) {
  1916. n++;
  1917. *to++ = IAC;
  1918. }
  1919. }
  1920. debug(F111,"copy_for_net","after",n);
  1921. return n;
  1922. }
  1923. #ifdef CK_SSL
  1924. /* S E N D S S L A U T H S B
  1925. * Send a SSL Authentication Subnegotiation to host and
  1926. * output appropriate Telnet Debug messages
  1927. *
  1928. * type - Sub Negotiation type
  1929. * data - ptr to buffer containing data
  1930. * len - len of buffer if not NUL terminated
  1931. *
  1932. * returns number of characters sent or error value
  1933. */
  1934. int
  1935. #ifdef CK_ANSIC
  1936. SendSSLAuthSB(int type, void *data, int len)
  1937. #else
  1938. SendSSLAuthSB(type,data,len) int type; void *data; int len;
  1939. #endif
  1940. {
  1941. int rc;
  1942. unsigned char *p = str_data + 3;
  1943. unsigned char *cd = (unsigned char *)data;
  1944. extern int sstelnet;
  1945. /* Check for invalid values */
  1946. if ( type != SSL_START && type != SSL_ACCEPT &&
  1947. type != SSL_REJECT)
  1948. return(0);
  1949. if (TELOPT_SB(TELOPT_START_TLS).start_tls.me_follows) {
  1950. if (ttchk() < 0)
  1951. return(0);
  1952. else
  1953. return(1);
  1954. }
  1955. if (len == -1) /* Use strlen() for len */
  1956. len = strlen((char *)cd);
  1957. /* Construct Message */
  1958. *p++ = sstelnet ? TELQUAL_REPLY : TELQUAL_IS;
  1959. *p++ = AUTHTYPE_SSL;
  1960. *p = AUTH_CLIENT_TO_SERVER;
  1961. *p |= auth_how;
  1962. #ifdef CK_ENCRYPTION
  1963. *p |= auth_crypt;
  1964. #endif
  1965. p++;
  1966. *p++ = type;
  1967. while (len-- > 0) {
  1968. if ((*p++ = *cd++) == IAC)
  1969. *p++ = IAC;
  1970. }
  1971. *p++ = IAC;
  1972. *p++ = SE;
  1973. /* Handle Telnet Debugging Messages */
  1974. if (deblog || tn_deb || debses) {
  1975. int i;
  1976. int deblen=p-str_data-2;
  1977. char *s=NULL;
  1978. int mode = AUTH_CLIENT_TO_SERVER | (auth_how & AUTH_HOW_MASK) |
  1979. (auth_crypt?AUTH_ENCRYPT_USING_TELOPT:AUTH_ENCRYPT_OFF);
  1980. switch (type) {
  1981. case SSL_START:
  1982. s = "START";
  1983. break;
  1984. case SSL_ACCEPT:
  1985. s = "ACCEPT";
  1986. break;
  1987. case SSL_REJECT:
  1988. s = "REJECT";
  1989. break;
  1990. }
  1991. ckmakxmsg(tn_msg,TN_MSG_LEN,
  1992. "TELNET SENT SB ",
  1993. TELOPT(TELOPT_AUTHENTICATION)," ",
  1994. str_data[3] == TELQUAL_REPLY ? "REPLY" :
  1995. str_data[3] == TELQUAL_IS ? "IS" : "???"," ",
  1996. AUTHTYPE_NAME(authentication_version)," ",
  1997. AUTHMODE_NAME(mode)," ",
  1998. s," ",NULL);
  1999. tn_hex((CHAR *)tn_msg,TN_MSG_LEN,&str_data[7],deblen-7);
  2000. ckstrncat(tn_msg,"IAC SE",TN_MSG_LEN);
  2001. debug(F100,tn_msg,"",0);
  2002. if (tn_deb || debses) tn_debug(tn_msg);
  2003. }
  2004. /* Send data */
  2005. #ifdef OS2
  2006. RequestTelnetMutex( SEM_INDEFINITE_WAIT );
  2007. #endif
  2008. rc = ttol((CHAR *)str_data, p - str_data);
  2009. #ifdef OS2
  2010. ReleaseTelnetMutex();
  2011. #endif
  2012. return(rc);
  2013. }
  2014. #endif /* CK_SSL */
  2015. int
  2016. tn_how_ok(int how)
  2017. {
  2018. switch ( tn_auth_how ) {
  2019. case TN_AUTH_HOW_ANY:
  2020. return(1);
  2021. case TN_AUTH_HOW_ONE_WAY:
  2022. return((how & AUTH_HOW_MASK) == AUTH_HOW_ONE_WAY);
  2023. case TN_AUTH_HOW_MUTUAL:
  2024. return((how & AUTH_HOW_MASK) == AUTH_HOW_MUTUAL);
  2025. default:
  2026. return(0);
  2027. }
  2028. }
  2029. int
  2030. tn_enc_ok(int enc)
  2031. {
  2032. switch ( tn_auth_enc ) {
  2033. case TN_AUTH_ENC_ANY:
  2034. if ((enc & AUTH_ENCRYPT_MASK) == AUTH_ENCRYPT_START_TLS &&
  2035. (!ck_ssleay_is_installed()
  2036. #ifdef CK_SSL
  2037. || !ssl_finished_messages ||
  2038. !(tls_active_flag || ssl_active_flag)
  2039. #endif /* CK_SSL */
  2040. )) {
  2041. #ifdef CK_SSL
  2042. if (!ssl_finished_messages)
  2043. debug(F100,"tn_enc_ok !ssl_finished_messages","",0);
  2044. #endif /* CK_SSL */
  2045. return(0);
  2046. }
  2047. return(1);
  2048. case TN_AUTH_ENC_NONE:
  2049. return((enc & AUTH_ENCRYPT_MASK) == AUTH_ENCRYPT_OFF);
  2050. case TN_AUTH_ENC_TELOPT:
  2051. return((enc & AUTH_ENCRYPT_MASK) == AUTH_ENCRYPT_USING_TELOPT);
  2052. case TN_AUTH_ENC_EXCH:
  2053. return((enc & AUTH_ENCRYPT_MASK) == AUTH_ENCRYPT_AFTER_EXCHANGE);
  2054. case TN_AUTH_ENC_TLS:
  2055. return(((enc & AUTH_ENCRYPT_MASK) == AUTH_ENCRYPT_START_TLS) &&
  2056. ck_ssleay_is_installed()
  2057. #ifdef CK_SSL
  2058. && ssl_finished_messages &&
  2059. (tls_active_flag || ssl_active_flag)
  2060. #endif /* CK_SSL */
  2061. );
  2062. default:
  2063. return(0);
  2064. }
  2065. }
  2066. static int
  2067. atok(int at) {
  2068. int i;
  2069. if ( auth_type_user[0] == AUTHTYPE_AUTO )
  2070. return(1);
  2071. if ( auth_type_user[0] == AUTHTYPE_NULL )
  2072. return(0);
  2073. for ( i=0;
  2074. i<AUTHTYPLSTSZ && auth_type_user[i] != AUTHTYPE_NULL;
  2075. i++ ) {
  2076. if ( auth_type_user[i] == at )
  2077. return(1);
  2078. }
  2079. return(0);
  2080. }
  2081. /*
  2082. * Function: Parse authentication send command
  2083. *
  2084. * Parameters:
  2085. * parsedat - the sub-command data.
  2086. *
  2087. * end_sub - index of the character in the 'parsedat' array which
  2088. * is the last byte in a sub-negotiation
  2089. *
  2090. * Returns: Kerberos error code.
  2091. */
  2092. static unsigned char send_list[512];
  2093. static int send_len = 0;
  2094. _PROTOTYP(static int auth_send, (unsigned char *parsedat, int end_sub));
  2095. static int
  2096. #ifdef CK_ANSIC
  2097. auth_resend(int type)
  2098. #else
  2099. auth_resend(type) int type;
  2100. #endif /* CK_ANSIC */
  2101. {
  2102. int i=2;
  2103. while (i+1 <= send_len) {
  2104. if (send_list[i] == type) {
  2105. int j;
  2106. send_len -= 2;
  2107. for (j = i; j < send_len; j++)
  2108. send_list[j] = send_list[j+2];
  2109. } else {
  2110. i += 2;
  2111. }
  2112. }
  2113. return(auth_send(send_list,send_len));
  2114. }
  2115. static int
  2116. #ifdef CK_ANSIC
  2117. auth_send(unsigned char *parsedat, int end_sub)
  2118. #else
  2119. auth_send(parsedat,end_sub) unsigned char *parsedat; int end_sub;
  2120. #endif
  2121. {
  2122. static unsigned char buf[4096];
  2123. unsigned char *pname;
  2124. int plen;
  2125. int r;
  2126. int i;
  2127. int mode;
  2128. #ifdef MIT_CURRENT
  2129. #ifdef CK_ENCRYPTION
  2130. krb5_data data;
  2131. krb5_enc_data encdata;
  2132. krb5_error_code code;
  2133. krb5_keyblock random_key;
  2134. #endif /* ENCRYPTION */
  2135. #endif /* MIT_CURRENT */
  2136. #ifdef KRB5
  2137. int krb5_msg = 0;
  2138. #endif /* KRB5 */
  2139. #ifdef KRB4
  2140. int krb4_msg = 0;
  2141. #endif /* KRB4 */
  2142. #ifdef GSSAPI_KRB5
  2143. int gssk5_msg = 0;
  2144. #endif /* GSSAPI_KRB5 */
  2145. int iaccnt=0;
  2146. #ifdef CK_SSL
  2147. if (TELOPT_SB(TELOPT_START_TLS).start_tls.me_follows)
  2148. return(AUTH_SUCCESS);
  2149. #endif /* CK_SSL */
  2150. auth_how = -1; /* We have not found an auth method */
  2151. auth_crypt = 0; /* We are not using encryption (yet) */
  2152. send_len = end_sub > 512 ? 512 : end_sub;
  2153. memcpy(send_list,parsedat,send_len);
  2154. /* Search the list of acceptable Authentication types sent from */
  2155. /* the host and find one that we support */
  2156. /* For Kerberos authentications, try to determine if we have a */
  2157. /* valid TGT, if not skip over the authentication type because */
  2158. /* we wouldn't be able to successfully login anyway. Perhaps */
  2159. /* there is another supported authentication which we could use */
  2160. #ifdef NO_FTP_AUTH
  2161. /* If the userid is "ftp" or "anonymous" refuse to perform AUTH */
  2162. /* for Kerberos or SRP. */
  2163. #endif /* NO_FTP_AUTH */
  2164. if ( auth_type_user[0] == AUTHTYPE_AUTO ) {
  2165. for (i = 2; i+1 <= end_sub; i += 2) {
  2166. #ifdef NTLM
  2167. if (parsedat[i] == AUTHTYPE_NTLM &&
  2168. ck_ntlm_is_valid(1) &&
  2169. ntlm_auth_send() == 0) {
  2170. if ((parsedat[i+1] & AUTH_WHO_MASK) == AUTH_CLIENT_TO_SERVER &&
  2171. tn_how_ok(parsedat[i+1]) && tn_enc_ok(parsedat[i+1])) {
  2172. #ifdef CK_ENCRYPTION
  2173. /* NTLM does not support Telnet Encryption */
  2174. if ((parsedat[i+1] & AUTH_ENCRYPT_MASK))
  2175. continue;
  2176. auth_crypt = parsedat[i+1] & AUTH_ENCRYPT_MASK;
  2177. #endif /* CK_ENCRYPTION */
  2178. TELOPT_ME_MODE(TELOPT_ENCRYPTION) = TN_NG_RF;
  2179. TELOPT_U_MODE(TELOPT_ENCRYPTION) = TN_NG_RF;
  2180. authentication_version = AUTHTYPE_NTLM;
  2181. auth_how = parsedat[i+1] & AUTH_HOW_MASK;
  2182. break;
  2183. }
  2184. }
  2185. #endif /* NTLM */
  2186. #ifdef CK_SSL
  2187. if ( parsedat[i] == AUTHTYPE_SSL && ssl_initialized &&
  2188. #ifdef SSLDLL
  2189. ck_ssleay_is_installed() &&
  2190. #endif /* SSLDLL */
  2191. !tls_active_flag && !ssl_active_flag
  2192. #ifndef USE_CERT_CB
  2193. && tls_load_certs(ssl_ctx,ssl_con,0)
  2194. #endif /* USE_CERT_CB */
  2195. ) {
  2196. if ((parsedat[i+1] & AUTH_WHO_MASK) == AUTH_CLIENT_TO_SERVER &&
  2197. tn_how_ok(parsedat[i+1]) && tn_enc_ok(parsedat[i+1])) {
  2198. #ifdef CK_ENCRYPTION
  2199. /* SSL does not support Telnet Encryption */
  2200. if ((parsedat[i+1] & AUTH_ENCRYPT_MASK))
  2201. continue;
  2202. auth_crypt = parsedat[i+1] & AUTH_ENCRYPT_MASK;
  2203. #endif /* CK_ENCRYPTION */
  2204. TELOPT_ME_MODE(TELOPT_ENCRYPTION) = TN_NG_RF;
  2205. TELOPT_U_MODE(TELOPT_ENCRYPTION) = TN_NG_RF;
  2206. authentication_version = AUTHTYPE_SSL;
  2207. auth_how = parsedat[i+1] & AUTH_HOW_MASK;
  2208. break;
  2209. }
  2210. }
  2211. #endif /* SSL */
  2212. #ifdef CK_SRP
  2213. if ( parsedat[i] == AUTHTYPE_SRP
  2214. #ifdef SRPDLL
  2215. && hSRP
  2216. #endif /* SRPDLL */
  2217. #ifdef NO_FTP_AUTH
  2218. && strcmp("ftp",szUserName) && strcmp("anonymous",szUserName)
  2219. #endif /* NO_FTP_AUTH */
  2220. ) {
  2221. if ((parsedat[i+1] & AUTH_WHO_MASK) == AUTH_CLIENT_TO_SERVER &&
  2222. tn_how_ok(parsedat[i+1]) && tn_enc_ok(parsedat[i+1])) {
  2223. #ifdef PRE_SRP_1_4_5
  2224. if (parsedat[i+1] & AUTH_ENCRYPT_MASK)
  2225. /* Do not support ENCRYPT_USING_TELOPT yet. */
  2226. continue;
  2227. #endif /* PRE_SRP_1_4_5 */
  2228. if (((parsedat[i+1] & AUTH_ENCRYPT_MASK) ==
  2229. AUTH_ENCRYPT_USING_TELOPT) &&
  2230. (TELOPT_ME_MODE(TELOPT_ENCRYPTION) == TN_NG_RF ||
  2231. TELOPT_U_MODE(TELOPT_ENCRYPTION) == TN_NG_RF))
  2232. continue;
  2233. auth_crypt = parsedat[i+1] & AUTH_ENCRYPT_MASK;
  2234. #ifdef CK_ENCRYPTION
  2235. if ( auth_crypt == AUTH_ENCRYPT_USING_TELOPT ) {
  2236. TELOPT_ME_MODE(TELOPT_ENCRYPTION) = TN_NG_MU;
  2237. TELOPT_U_MODE(TELOPT_ENCRYPTION) = TN_NG_MU;
  2238. }
  2239. #endif /* CK_ENCRYPTION */
  2240. #ifdef CK_SSL
  2241. if ( auth_crypt == AUTH_ENCRYPT_START_TLS &&
  2242. ck_ssleay_is_installed() &&
  2243. (tls_active_flag || ssl_active_flag) ) {
  2244. TELOPT_ME_MODE(TELOPT_ENCRYPTION) = TN_NG_RF;
  2245. TELOPT_U_MODE(TELOPT_ENCRYPTION) = TN_NG_RF;
  2246. }
  2247. #endif /* CK_SSL */
  2248. authentication_version = AUTHTYPE_SRP;
  2249. auth_how = parsedat[i+1] & AUTH_HOW_MASK;
  2250. break;
  2251. }
  2252. }
  2253. #endif /* SRP */
  2254. #ifdef GSSAPI_KRB5
  2255. if (parsedat[i] == AUTHTYPE_GSSAPI_KRB5 &&
  2256. (parsedat[i+1] & AUTH_ENCRYPT_MASK) ==
  2257. AUTH_ENCRYPT_AFTER_EXCHANGE &&
  2258. #ifdef OS2
  2259. hGSSAPI &&
  2260. #endif /* OS2 */
  2261. #ifdef NO_FTP_AUTH
  2262. strcmp("ftp",szUserName) && strcmp("anonymous",szUserName) &&
  2263. #endif /* NO_FTP_AUTH */
  2264. ck_gssapi_is_installed() && !gssk5_msg)
  2265. {
  2266. if ( !gssk5_auth_send(parsedat[i+1] & AUTH_HOW_MASK,
  2267. parsedat[i+1] & AUTH_ENCRYPT_MASK,
  2268. parsedat[i+1] & INI_CRED_FWD_MASK) )
  2269. {
  2270. /* If we are auto-getting TGTs, try */
  2271. if ( !ck_krb5_is_tgt_valid() ) {
  2272. printf("Kerberos 5: Ticket Getting Ticket not valid.\r\n");
  2273. }
  2274. gssk5_msg = 1;
  2275. }
  2276. else if ((parsedat[i+1] & AUTH_WHO_MASK) ==
  2277. AUTH_CLIENT_TO_SERVER &&
  2278. tn_how_ok(parsedat[i+1]) && tn_enc_ok(parsedat[i+1])) {
  2279. auth_crypt = parsedat[i+1] & AUTH_ENCRYPT_MASK;
  2280. #ifdef CK_ENCRYPTION
  2281. if ( auth_crypt == AUTH_ENCRYPT_AFTER_EXCHANGE ) {
  2282. TELOPT_ME_MODE(TELOPT_ENCRYPTION) = TN_NG_RF;
  2283. TELOPT_U_MODE(TELOPT_ENCRYPTION) = TN_NG_RF;
  2284. }
  2285. #endif /* CK_ENCRYPTION */
  2286. auth_fwd = parsedat[i+1] & INI_CRED_FWD_MASK;
  2287. authentication_version = AUTHTYPE_GSSAPI_KRB5;
  2288. auth_how = parsedat[i+1] & AUTH_HOW_MASK;
  2289. break;
  2290. }
  2291. }
  2292. #endif /* GSSAPI_KRB5 */
  2293. #ifdef KRB5
  2294. if (parsedat[i] == AUTHTYPE_KERBEROS_V5 &&
  2295. #ifdef OS2
  2296. hKRB5_32 &&
  2297. #endif /* OS2 */
  2298. #ifdef NO_FTP_AUTH
  2299. strcmp("ftp",szUserName) && strcmp("anonymous",szUserName) &&
  2300. #endif /* NO_FTP_AUTH */
  2301. ck_krb5_is_installed() && !krb5_msg) {
  2302. /* Without encryption we can't perform mutual authentication */
  2303. if ( (parsedat[i+1] & AUTH_HOW_MASK) == AUTH_HOW_MUTUAL &&
  2304. !ck_crypt_is_installed())
  2305. continue;
  2306. /* Skip over entries that request credential forwarding */
  2307. /* if we are not forwarding. */
  2308. if ((!forward_flag && (parsedat[i+1] & INI_CRED_FWD_MASK)) ||
  2309. (forward_flag &&
  2310. ((parsedat[i+1] & AUTH_HOW_MASK) == AUTH_HOW_ONE_WAY)))
  2311. continue;
  2312. if ( !k5_auth_send(parsedat[i+1] & AUTH_HOW_MASK,
  2313. parsedat[i+1] & AUTH_ENCRYPT_MASK,
  2314. parsedat[i+1] & INI_CRED_FWD_MASK) )
  2315. {
  2316. /* If we are auto-getting TGTs, try */
  2317. if ( !ck_krb5_is_tgt_valid() ) {
  2318. printf("Kerberos 5: Ticket Getting Ticket not valid.\r\n");
  2319. }
  2320. krb5_msg = 1;
  2321. }
  2322. else if ((parsedat[i+1] & AUTH_WHO_MASK) ==
  2323. AUTH_CLIENT_TO_SERVER &&
  2324. tn_how_ok(parsedat[i+1]) && tn_enc_ok(parsedat[i+1])) {
  2325. if (((parsedat[i+1] & AUTH_ENCRYPT_MASK) ==
  2326. AUTH_ENCRYPT_USING_TELOPT) &&
  2327. (TELOPT_ME_MODE(TELOPT_ENCRYPTION) == TN_NG_RF ||
  2328. TELOPT_U_MODE(TELOPT_ENCRYPTION) == TN_NG_RF))
  2329. continue;
  2330. if (((parsedat[i+1] & AUTH_ENCRYPT_MASK) ==
  2331. AUTH_ENCRYPT_START_TLS) &&
  2332. (!ck_ssleay_is_installed()
  2333. #ifdef CK_SSL
  2334. || !(tls_active_flag || ssl_active_flag)
  2335. #endif /* CK_SSL */
  2336. ))
  2337. continue;
  2338. auth_crypt = parsedat[i+1] & AUTH_ENCRYPT_MASK;
  2339. #ifdef CK_ENCRYPTION
  2340. if ( auth_crypt == AUTH_ENCRYPT_USING_TELOPT ) {
  2341. TELOPT_ME_MODE(TELOPT_ENCRYPTION) = TN_NG_MU;
  2342. TELOPT_U_MODE(TELOPT_ENCRYPTION) = TN_NG_MU;
  2343. }
  2344. #endif /* CK_ENCRYPTION */
  2345. #ifdef CK_SSL
  2346. if ( auth_crypt == AUTH_ENCRYPT_START_TLS &&
  2347. ck_ssleay_is_installed() &&
  2348. (tls_active_flag || ssl_active_flag) ) {
  2349. TELOPT_ME_MODE(TELOPT_ENCRYPTION) = TN_NG_RF;
  2350. TELOPT_U_MODE(TELOPT_ENCRYPTION) = TN_NG_RF;
  2351. }
  2352. #endif /* CK_SSL */
  2353. auth_fwd = parsedat[i+1] & INI_CRED_FWD_MASK;
  2354. authentication_version = AUTHTYPE_KERBEROS_V5;
  2355. auth_how = parsedat[i+1] & AUTH_HOW_MASK;
  2356. if ( auth_how == AUTH_HOW_ONE_WAY ) {
  2357. TELOPT_ME_MODE(TELOPT_ENCRYPTION) = TN_NG_RF;
  2358. TELOPT_U_MODE(TELOPT_ENCRYPTION) = TN_NG_RF;
  2359. }
  2360. break;
  2361. }
  2362. }
  2363. #endif /* KRB5 */
  2364. #ifdef KRB4
  2365. if (parsedat[i] == AUTHTYPE_KERBEROS_V4 &&
  2366. #ifdef OS2
  2367. hKRB4_32 &&
  2368. #endif /* OS2 */
  2369. #ifdef NO_FTP_AUTH
  2370. strcmp("ftp",szUserName) && strcmp("anonymous",szUserName) &&
  2371. #endif /* NO_FTP_AUTH */
  2372. ck_krb4_is_installed() && !krb4_msg) {
  2373. int rc = 0;
  2374. /* Without encryption we can't perform mutual authentication */
  2375. if ( (parsedat[i+1] & AUTH_HOW_MASK) == AUTH_HOW_MUTUAL &&
  2376. !ck_crypt_is_installed() )
  2377. continue;
  2378. if ( !k4_auth_send() )
  2379. {
  2380. /* If we are auto-getting TGTs, try */
  2381. if ( !ck_krb4_is_tgt_valid() ) {
  2382. printf("Kerberos 4: Ticket Getting Ticket not valid.\r\n");
  2383. }
  2384. krb4_msg = 1;
  2385. }
  2386. else if ((parsedat[i+1] & AUTH_WHO_MASK) ==
  2387. AUTH_CLIENT_TO_SERVER &&
  2388. tn_how_ok(parsedat[i+1]) && tn_enc_ok(parsedat[i+1])) {
  2389. #ifdef CK_ENCRYPTION
  2390. if ((parsedat[i+1] & AUTH_ENCRYPT_MASK) &&
  2391. (TELOPT_ME_MODE(TELOPT_ENCRYPTION) == TN_NG_RF ||
  2392. TELOPT_U_MODE(TELOPT_ENCRYPTION) == TN_NG_RF))
  2393. continue;
  2394. auth_crypt = parsedat[i+1] & AUTH_ENCRYPT_MASK;
  2395. if ( auth_crypt == AUTH_ENCRYPT_USING_TELOPT ) {
  2396. TELOPT_ME_MODE(TELOPT_ENCRYPTION) = TN_NG_MU;
  2397. TELOPT_U_MODE(TELOPT_ENCRYPTION) = TN_NG_MU;
  2398. }
  2399. #endif /* CK_ENCRYPTION */
  2400. authentication_version = AUTHTYPE_KERBEROS_V4;
  2401. auth_how = parsedat[i+1] & AUTH_HOW_MASK;
  2402. if ( auth_how == AUTH_HOW_ONE_WAY ) {
  2403. TELOPT_ME_MODE(TELOPT_ENCRYPTION) = TN_NG_RF;
  2404. TELOPT_U_MODE(TELOPT_ENCRYPTION) = TN_NG_RF;
  2405. }
  2406. break;
  2407. }
  2408. }
  2409. #endif /* KRB4 */
  2410. }
  2411. } else {
  2412. for (i = 2; i+1 <= end_sub; i += 2) {
  2413. #ifdef CK_SSL
  2414. if ( atok(AUTHTYPE_SSL) && parsedat[i] == AUTHTYPE_SSL &&
  2415. #ifdef SSLDLL
  2416. ck_ssleay_is_installed() &&
  2417. #endif /* SSLDLL */
  2418. !tls_active_flag && !ssl_active_flag && ssl_initialized
  2419. #ifndef USE_CERT_CB
  2420. && tls_load_certs(ssl_ctx,ssl_con,0)
  2421. #endif /* USE_CERT_CB */
  2422. )
  2423. {
  2424. if ((parsedat[i+1] & AUTH_WHO_MASK) == AUTH_CLIENT_TO_SERVER &&
  2425. tn_how_ok(parsedat[i+1]) && tn_enc_ok(parsedat[i+1])) {
  2426. #ifdef CK_ENCRYPTION
  2427. /* SSL does not support Telnet Encryption */
  2428. if ((parsedat[i+1] & AUTH_ENCRYPT_MASK))
  2429. continue;
  2430. auth_crypt = parsedat[i+1] & AUTH_ENCRYPT_MASK;
  2431. #endif /* CK_ENCRYPTION */
  2432. TELOPT_ME_MODE(TELOPT_ENCRYPTION) = TN_NG_RF;
  2433. TELOPT_U_MODE(TELOPT_ENCRYPTION) = TN_NG_RF;
  2434. authentication_version = AUTHTYPE_SSL;
  2435. auth_how = parsedat[i+1] & AUTH_HOW_MASK;
  2436. break;
  2437. }
  2438. }
  2439. #endif /* SSL */
  2440. #ifdef CK_SRP
  2441. if ( atok(AUTHTYPE_SRP) &&
  2442. parsedat[i] == AUTHTYPE_SRP
  2443. #ifdef SRPDLL
  2444. && hSRP
  2445. #endif /* SRPDLL */
  2446. #ifdef NO_FTP_AUTH
  2447. && strcmp("ftp",szUserName) && strcmp("anonymous",szUserName)
  2448. #endif /* NO_FTP_AUTH */
  2449. ) {
  2450. if ((parsedat[i+1] & AUTH_WHO_MASK) == AUTH_CLIENT_TO_SERVER &&
  2451. tn_how_ok(parsedat[i+1]) && tn_enc_ok(parsedat[i+1])) {
  2452. #ifdef PRE_SRP_1_4_5
  2453. if (parsedat[i+1] & AUTH_ENCRYPT_MASK)
  2454. /* Do not support ENCRYPT_USING_TELOPT yet. */
  2455. continue;
  2456. #endif /* PRE_SRP_1_4_5 */
  2457. if (((parsedat[i+1] & AUTH_ENCRYPT_MASK) ==
  2458. AUTH_ENCRYPT_USING_TELOPT) &&
  2459. (TELOPT_ME_MODE(TELOPT_ENCRYPTION) == TN_NG_RF ||
  2460. TELOPT_U_MODE(TELOPT_ENCRYPTION) == TN_NG_RF))
  2461. continue;
  2462. if (((parsedat[i+1] & AUTH_ENCRYPT_MASK) ==
  2463. AUTH_ENCRYPT_START_TLS) &&
  2464. (!ck_ssleay_is_installed()
  2465. #ifdef CK_SSL
  2466. || !(tls_active_flag || ssl_active_flag)
  2467. #endif /* CK_SSL */
  2468. ))
  2469. continue;
  2470. auth_crypt = parsedat[i+1] & AUTH_ENCRYPT_MASK;
  2471. #ifdef CK_ENCRYPTION
  2472. if ( auth_crypt == AUTH_ENCRYPT_USING_TELOPT ) {
  2473. TELOPT_ME_MODE(TELOPT_ENCRYPTION) = TN_NG_MU;
  2474. TELOPT_U_MODE(TELOPT_ENCRYPTION) = TN_NG_MU;
  2475. }
  2476. #endif /* CK_ENCRYPTION */
  2477. #ifdef CK_SSL
  2478. if ( auth_crypt == AUTH_ENCRYPT_START_TLS &&
  2479. ck_ssleay_is_installed() &&
  2480. (tls_active_flag || ssl_active_flag) ) {
  2481. TELOPT_ME_MODE(TELOPT_ENCRYPTION) = TN_NG_RF;
  2482. TELOPT_U_MODE(TELOPT_ENCRYPTION) = TN_NG_RF;
  2483. }
  2484. #endif /* CK_SSL */
  2485. authentication_version = AUTHTYPE_SRP;
  2486. auth_how = parsedat[i+1] & AUTH_HOW_MASK;
  2487. break;
  2488. }
  2489. }
  2490. #endif /* SRP */
  2491. #ifdef GSSAPI_KRB5
  2492. if (atok(AUTHTYPE_GSSAPI_KRB5) &&
  2493. parsedat[i] == AUTHTYPE_GSSAPI_KRB5 &&
  2494. (parsedat[i+1] & AUTH_ENCRYPT_MASK) ==
  2495. AUTH_ENCRYPT_AFTER_EXCHANGE &&
  2496. #ifdef OS2
  2497. hGSSAPI &&
  2498. #endif /* OS2 */
  2499. #ifdef NO_FTP_AUTH
  2500. strcmp("ftp",szUserName) && strcmp("anonymous",szUserName) &&
  2501. #endif /* NO_FTP_AUTH */
  2502. ck_gssapi_is_installed() && !gssk5_msg)
  2503. {
  2504. if ( !gssk5_auth_send(parsedat[i+1] & AUTH_HOW_MASK,
  2505. parsedat[i+1] & AUTH_ENCRYPT_MASK,
  2506. parsedat[i+1] & INI_CRED_FWD_MASK) )
  2507. {
  2508. /* If we are auto-getting TGTs, try */
  2509. if ( !ck_krb5_is_tgt_valid() ) {
  2510. printf("Kerberos 5: Ticket Getting Ticket not valid.\r\n");
  2511. }
  2512. gssk5_msg = 1;
  2513. }
  2514. else if ((parsedat[i+1] & AUTH_WHO_MASK) ==
  2515. AUTH_CLIENT_TO_SERVER &&
  2516. tn_how_ok(parsedat[i+1]) && tn_enc_ok(parsedat[i+1])) {
  2517. auth_crypt = parsedat[i+1] & AUTH_ENCRYPT_MASK;
  2518. #ifdef CK_ENCRYPTION
  2519. if ( auth_crypt == AUTH_ENCRYPT_AFTER_EXCHANGE ) {
  2520. TELOPT_ME_MODE(TELOPT_ENCRYPTION) = TN_NG_RF;
  2521. TELOPT_U_MODE(TELOPT_ENCRYPTION) = TN_NG_RF;
  2522. }
  2523. #endif /* CK_ENCRYPTION */
  2524. auth_fwd = parsedat[i+1] & INI_CRED_FWD_MASK;
  2525. authentication_version = AUTHTYPE_GSSAPI_KRB5;
  2526. auth_how = parsedat[i+1] & AUTH_HOW_MASK;
  2527. break;
  2528. }
  2529. }
  2530. #endif /* GSSAPI_KRB5 */
  2531. #ifdef KRB5
  2532. if ( atok(AUTHTYPE_KERBEROS_V5) &&
  2533. parsedat[i] == AUTHTYPE_KERBEROS_V5 &&
  2534. #ifdef OS2
  2535. hKRB5_32 &&
  2536. #endif /* OS2 */
  2537. #ifdef NO_FTP_AUTH
  2538. strcmp("ftp",szUserName) && strcmp("anonymous",szUserName) &&
  2539. #endif /* NO_FTP_AUTH */
  2540. ck_krb5_is_installed() && !krb5_msg) {
  2541. /* Without encryption we can't perform mutual authentication */
  2542. if ( (parsedat[i+1] & AUTH_HOW_MASK) == AUTH_HOW_MUTUAL &&
  2543. !ck_crypt_is_installed())
  2544. continue;
  2545. /* Skip over entries that request credential forwarding */
  2546. /* if we are not forwarding. */
  2547. if ((!forward_flag && (parsedat[i+1] & INI_CRED_FWD_MASK)) ||
  2548. (forward_flag &&
  2549. ((parsedat[i+1] & AUTH_HOW_MASK) == AUTH_HOW_ONE_WAY)))
  2550. continue;
  2551. if ( !k5_auth_send(parsedat[i+1] & AUTH_HOW_MASK,
  2552. parsedat[i+1] & AUTH_ENCRYPT_MASK,
  2553. parsedat[i+1] & INI_CRED_FWD_MASK) )
  2554. {
  2555. /* If we are auto-getting TGTs, try */
  2556. if ( !ck_krb5_is_tgt_valid() ) {
  2557. printf(
  2558. "Kerberos 5: Ticket Getting Ticket not valid.\r\n");
  2559. }
  2560. krb5_msg = 1;
  2561. }
  2562. else if ((parsedat[i+1] & AUTH_WHO_MASK) ==
  2563. AUTH_CLIENT_TO_SERVER &&
  2564. tn_how_ok(parsedat[i+1]) && tn_enc_ok(parsedat[i+1]))
  2565. {
  2566. if (((parsedat[i+1] & AUTH_ENCRYPT_MASK) ==
  2567. AUTH_ENCRYPT_USING_TELOPT) &&
  2568. (TELOPT_ME_MODE(TELOPT_ENCRYPTION) == TN_NG_RF ||
  2569. TELOPT_U_MODE(TELOPT_ENCRYPTION) == TN_NG_RF))
  2570. continue;
  2571. if (((parsedat[i+1] & AUTH_ENCRYPT_MASK) ==
  2572. AUTH_ENCRYPT_START_TLS) &&
  2573. (!ck_ssleay_is_installed()
  2574. #ifdef CK_SSL
  2575. || !(tls_active_flag || ssl_active_flag)
  2576. #endif /* CK_SSL */
  2577. ))
  2578. continue;
  2579. auth_crypt = parsedat[i+1] & AUTH_ENCRYPT_MASK;
  2580. #ifdef CK_ENCRYPTION
  2581. if (auth_crypt) {
  2582. TELOPT_ME_MODE(TELOPT_ENCRYPTION) = TN_NG_MU;
  2583. TELOPT_U_MODE(TELOPT_ENCRYPTION) = TN_NG_MU;
  2584. }
  2585. #endif /* CK_ENCRYPTION */
  2586. #ifdef CK_SSL
  2587. if ( auth_crypt == AUTH_ENCRYPT_START_TLS &&
  2588. ck_ssleay_is_installed() &&
  2589. (tls_active_flag || ssl_active_flag) ) {
  2590. TELOPT_ME_MODE(TELOPT_ENCRYPTION) = TN_NG_RF;
  2591. TELOPT_U_MODE(TELOPT_ENCRYPTION) = TN_NG_RF;
  2592. }
  2593. #endif /* CK_SSL */
  2594. authentication_version = AUTHTYPE_KERBEROS_V5;
  2595. auth_how = parsedat[i+1] & AUTH_HOW_MASK;
  2596. if ( auth_how == AUTH_HOW_ONE_WAY ) {
  2597. TELOPT_ME_MODE(TELOPT_ENCRYPTION) = TN_NG_RF;
  2598. TELOPT_U_MODE(TELOPT_ENCRYPTION) = TN_NG_RF;
  2599. }
  2600. break;
  2601. }
  2602. }
  2603. #endif /* KRB5 */
  2604. #ifdef KRB4
  2605. if ( atok(AUTHTYPE_KERBEROS_V4) &&
  2606. parsedat[i] == AUTHTYPE_KERBEROS_V4 &&
  2607. #ifdef OS2
  2608. hKRB4_32 &&
  2609. #endif /* OS2 */
  2610. #ifdef NO_FTP_AUTH
  2611. strcmp("ftp",szUserName) && strcmp("anonymous",szUserName) &&
  2612. #endif /* NO_FTP_AUTH */
  2613. ck_krb4_is_installed() && !krb4_msg) {
  2614. int rc = 0;
  2615. /* Without encryption we can't perform mutual authentication */
  2616. if ( (parsedat[i+1] & AUTH_HOW_MASK) == AUTH_HOW_MUTUAL &&
  2617. !ck_crypt_is_installed())
  2618. continue;
  2619. if ( !k4_auth_send() )
  2620. {
  2621. /* If we are auto-getting TGTs, try */
  2622. if ( !ck_krb4_is_tgt_valid() ) {
  2623. printf("Kerberos 4: Ticket Getting Ticket not valid.\r\n");
  2624. }
  2625. krb4_msg = 1;
  2626. }
  2627. else if ((parsedat[i+1] & AUTH_WHO_MASK) ==
  2628. AUTH_CLIENT_TO_SERVER &&
  2629. tn_how_ok(parsedat[i+1]) && tn_enc_ok(parsedat[i+1]))
  2630. {
  2631. #ifdef CK_ENCRYPTION
  2632. if ((parsedat[i+1] & AUTH_ENCRYPT_MASK) &&
  2633. (TELOPT_ME_MODE(TELOPT_ENCRYPTION) == TN_NG_RF ||
  2634. TELOPT_U_MODE(TELOPT_ENCRYPTION) == TN_NG_RF))
  2635. continue;
  2636. auth_crypt = parsedat[i+1] & AUTH_ENCRYPT_MASK;
  2637. if (auth_crypt) {
  2638. TELOPT_ME_MODE(TELOPT_ENCRYPTION) = TN_NG_MU;
  2639. TELOPT_U_MODE(TELOPT_ENCRYPTION) = TN_NG_MU;
  2640. }
  2641. #endif /* CK_ENCRYPTION */
  2642. authentication_version = AUTHTYPE_KERBEROS_V4;
  2643. auth_how = parsedat[i+1] & AUTH_HOW_MASK;
  2644. if ( auth_how == AUTH_HOW_ONE_WAY ) {
  2645. TELOPT_ME_MODE(TELOPT_ENCRYPTION) = TN_NG_RF;
  2646. TELOPT_U_MODE(TELOPT_ENCRYPTION) = TN_NG_RF;
  2647. }
  2648. break;
  2649. }
  2650. }
  2651. #endif /* KRB4 */
  2652. #ifdef NTLM
  2653. if ( atok(AUTHTYPE_NTLM) &&
  2654. parsedat[i] == AUTHTYPE_NTLM &&
  2655. ck_ntlm_is_valid(1) &&
  2656. ntlm_auth_send() == 0) {
  2657. if ((parsedat[i+1] & AUTH_WHO_MASK) == AUTH_CLIENT_TO_SERVER &&
  2658. tn_how_ok(parsedat[i+1]) && tn_enc_ok(parsedat[i+1])) {
  2659. #ifdef CK_ENCRYPTION
  2660. /* NTLM does not support Telnet Encryption */
  2661. if ((parsedat[i+1] & AUTH_ENCRYPT_MASK))
  2662. continue;
  2663. auth_crypt = parsedat[i+1] & AUTH_ENCRYPT_MASK;
  2664. #endif /* CK_ENCRYPTION */
  2665. TELOPT_ME_MODE(TELOPT_ENCRYPTION) = TN_NG_RF;
  2666. TELOPT_U_MODE(TELOPT_ENCRYPTION) = TN_NG_RF;
  2667. authentication_version = AUTHTYPE_NTLM;
  2668. auth_how = parsedat[i+1] & AUTH_HOW_MASK;
  2669. break;
  2670. }
  2671. }
  2672. #endif /* NTLM */
  2673. }
  2674. }
  2675. if (auth_how == -1) { /* Did we find one? */
  2676. switch ( auth_type_user[0] ) { /* If not, abort the negotiation */
  2677. case AUTHTYPE_NULL:
  2678. auth_abort("User refused to accept any authentication method",0);
  2679. break;
  2680. case AUTHTYPE_AUTO:
  2681. auth_abort("No authentication method available", 0);
  2682. break;
  2683. default: {
  2684. char msg[80];
  2685. ckmakmsg(msg,80,AUTHTYPE_NAME(auth_type_user[0]),
  2686. " could not be negotiated",NULL,NULL
  2687. );
  2688. auth_abort(msg, 0);
  2689. }
  2690. }
  2691. auth_finished(AUTH_REJECT);
  2692. return AUTH_FAILURE;
  2693. }
  2694. printf("Authenticating with %s\r\n",
  2695. AUTHTYPE_NAME(authentication_version));
  2696. /* Send Telnet Auth Name message (if necessary) */
  2697. switch ( authentication_version ) {
  2698. case AUTHTYPE_SRP:
  2699. case AUTHTYPE_KERBEROS_V4:
  2700. case AUTHTYPE_KERBEROS_V5:
  2701. case AUTHTYPE_GSSAPI_KRB5:
  2702. /* if we do not have a name to login with get one now. */
  2703. while ( szUserName[0] == '\0' ) {
  2704. extern char * tn_pr_uid;
  2705. int ok = uq_txt(NULL,
  2706. tn_pr_uid && tn_pr_uid[0] ? tn_pr_uid : "Host Userid: ",
  2707. 1, NULL, szUserName, 63, NULL,DEFAULT_UQ_TIMEOUT);
  2708. if ( !ok )
  2709. return AUTH_FAILURE;
  2710. }
  2711. plen = strlen(szUserName);
  2712. pname = (unsigned char *) szUserName;
  2713. /* Construct Telnet Debugging Message */
  2714. if (deblog || tn_deb || debses) {
  2715. ckmakxmsg(tn_msg,TN_MSG_LEN,
  2716. "TELNET SENT SB ",TELOPT(TELOPT_AUTHENTICATION),
  2717. " NAME ",(char *)pname," IAC SE",NULL,
  2718. NULL,NULL,NULL,NULL,NULL,NULL
  2719. );
  2720. debug(F100,tn_msg,"",0);
  2721. if (tn_deb || debses) tn_debug(tn_msg);
  2722. }
  2723. /* Construct and send Authentication Name subnegotiation */
  2724. if ( plen < sizeof(buf) - 6 ) {
  2725. sprintf((char *)buf, "%c%c%c%c", IAC, SB,
  2726. TELOPT_AUTHENTICATION,
  2727. TELQUAL_NAME);
  2728. memcpy(&buf[4], pname, plen); /* safe */
  2729. sprintf((char *)&buf[plen + 4], "%c%c", IAC, SE); /* safe */
  2730. #ifdef OS2
  2731. RequestTelnetMutex( SEM_INDEFINITE_WAIT );
  2732. #endif
  2733. ttol((CHAR *)buf, plen+6);
  2734. #ifdef OS2
  2735. ReleaseTelnetMutex();
  2736. #endif
  2737. } else {
  2738. sprintf((char *)buf, "%c%c%c%c%c%c", IAC, SB,
  2739. TELOPT_AUTHENTICATION,
  2740. TELQUAL_NAME, IAC, SE); /* safe */
  2741. #ifdef OS2
  2742. RequestTelnetMutex( SEM_INDEFINITE_WAIT );
  2743. #endif
  2744. ttol((CHAR *)buf, 6);
  2745. #ifdef OS2
  2746. ReleaseTelnetMutex();
  2747. #endif
  2748. }
  2749. }
  2750. /* Construct Authentication Mode subnegotiation message (if necessary) */
  2751. switch ( authentication_version ) {
  2752. case AUTHTYPE_SRP:
  2753. case AUTHTYPE_KERBEROS_V4:
  2754. case AUTHTYPE_KERBEROS_V5:
  2755. case AUTHTYPE_GSSAPI_KRB5:
  2756. case AUTHTYPE_NTLM:
  2757. mode = AUTH_CLIENT_TO_SERVER | (auth_how & AUTH_HOW_MASK) | auth_crypt
  2758. #ifdef USE_INI_CRED_FWD
  2759. | (((authentication_version == AUTHTYPE_KERBEROS_V5) &&
  2760. auth_fwd)?INI_CRED_FWD_ON:INI_CRED_FWD_OFF)
  2761. #endif /* USE_INI_CRED_FWD */
  2762. ;
  2763. sprintf((char *)buf, "%c%c%c%c%c%c%c",
  2764. IAC, SB, TELOPT_AUTHENTICATION,
  2765. TELQUAL_IS,
  2766. authentication_version,
  2767. mode,
  2768. KRB_AUTH); /* safe */
  2769. break;
  2770. }
  2771. /* Send initial authentication data */
  2772. switch ( authentication_version ) {
  2773. #ifdef CK_SSL
  2774. case AUTHTYPE_SSL:
  2775. SendSSLAuthSB(SSL_START,NULL,0);
  2776. break;
  2777. #endif /* SSL */
  2778. #ifdef CK_SRP
  2779. case AUTHTYPE_SRP:
  2780. sprintf(&buf[7], "%c%c", IAC, SE); /* safe */
  2781. if (deblog || tn_deb || debses) {
  2782. ckmakxmsg(tn_msg,TN_MSG_LEN,
  2783. "TELNET SENT SB ",TELOPT(TELOPT_AUTHENTICATION),
  2784. " IS ",AUTHTYPE_NAME(authentication_version),
  2785. " AUTH ",AUTHMODE_NAME(mode)," IAC SE",
  2786. NULL,NULL,NULL,NULL,NULL
  2787. );
  2788. debug(F100,tn_msg,"",0);
  2789. if (tn_deb || debses) tn_debug(tn_msg);
  2790. }
  2791. #ifdef OS2
  2792. RequestTelnetMutex( SEM_INDEFINITE_WAIT );
  2793. #endif
  2794. ttol((CHAR *)buf, 9);
  2795. #ifdef OS2
  2796. ReleaseTelnetMutex();
  2797. #endif
  2798. break;
  2799. #endif /* SRP */
  2800. #ifdef NTLM
  2801. case AUTHTYPE_NTLM: {
  2802. int length = 0;
  2803. for ( i=0 ; i<NTLMSecBuf[0].cbBuffer ; i++ ) {
  2804. if ( ((char *)NTLMSecBuf[0].pvBuffer)[i] == IAC )
  2805. iaccnt++;
  2806. }
  2807. if ( ( 2*sizeof(ULONG) + NTLMSecBuf[0].cbBuffer + iaccnt + 10) <
  2808. sizeof(buf) ) {
  2809. length = copy_for_net(&buf[7],(char *)&NTLMSecBuf[0],
  2810. 2*sizeof(ULONG));
  2811. length += copy_for_net(&buf[7+length], NTLMSecBuf[0].pvBuffer,
  2812. NTLMSecBuf[0].cbBuffer);
  2813. }
  2814. sprintf(&buf[7+length], "%c%c", IAC, SE);
  2815. if (deblog || tn_deb || debses) {
  2816. int i;
  2817. ckmakxmsg(tn_msg,TN_MSG_LEN,
  2818. "TELNET SENT SB ",TELOPT(TELOPT_AUTHENTICATION),
  2819. " IS ",AUTHTYPE_NAME(authentication_version)," ",
  2820. AUTHMODE_NAME(mode)," NTLM_AUTH ",
  2821. NULL,NULL,NULL,NULL,NULL
  2822. );
  2823. tn_hex((char *)tn_msg,TN_MSG_LEN,&buf[7],length);
  2824. ckstrncat(tn_msg,"IAC SE",TN_MSG_LEN);
  2825. debug(F100,tn_msg,"",0);
  2826. if (tn_deb || debses) tn_debug(tn_msg);
  2827. }
  2828. #ifdef OS2
  2829. RequestTelnetMutex( SEM_INDEFINITE_WAIT );
  2830. #endif
  2831. ttol((CHAR *)buf, length+9);
  2832. #ifdef OS2
  2833. ReleaseTelnetMutex();
  2834. #endif
  2835. break;
  2836. }
  2837. #endif /* NTLM */
  2838. #ifdef KRB4
  2839. case AUTHTYPE_KERBEROS_V4:
  2840. for ( i=0 ; i<k4_auth.length ; i++ ) {
  2841. if ( k4_auth.dat[i] == IAC )
  2842. iaccnt++;
  2843. }
  2844. if ( k4_auth.length + iaccnt + 10 < sizeof(buf) )
  2845. k4_auth.length = copy_for_net(&buf[7], k4_auth.dat, k4_auth.length);
  2846. else
  2847. k4_auth.length = 0;
  2848. sprintf(&buf[k4_auth.length+7], "%c%c", IAC, SE);
  2849. if (deblog || tn_deb || debses) {
  2850. int i;
  2851. ckmakxmsg(tn_msg,TN_MSG_LEN,
  2852. "TELNET SENT SB ",TELOPT(TELOPT_AUTHENTICATION)," IS ",
  2853. AUTHTYPE_NAME(authentication_version)," ",
  2854. AUTHMODE_NAME(mode)," AUTH ",
  2855. NULL,NULL,NULL,NULL,NULL
  2856. );
  2857. tn_hex((char *)tn_msg,TN_MSG_LEN,&buf[7],k4_auth.length);
  2858. ckstrncat(tn_msg,"IAC SE",TN_MSG_LEN);
  2859. debug(F100,tn_msg,"",0);
  2860. if (tn_deb || debses) tn_debug(tn_msg);
  2861. }
  2862. #ifdef OS2
  2863. RequestTelnetMutex( SEM_INDEFINITE_WAIT );
  2864. #endif
  2865. ttol((CHAR *)buf, k4_auth.length+9);
  2866. #ifdef OS2
  2867. ReleaseTelnetMutex();
  2868. #endif
  2869. #ifndef REMOVE_FOR_EXPORT
  2870. #ifdef CK_ENCRYPTION
  2871. /*
  2872. * If we are doing mutual authentication, get set up to send
  2873. * the challenge, and verify it when the response comes back.
  2874. */
  2875. if ((auth_how & AUTH_HOW_MASK) == AUTH_HOW_MUTUAL) {
  2876. register int i;
  2877. int rc = 0;
  2878. #ifdef MIT_CURRENT
  2879. data.data = cred.session;
  2880. data.length = 8; /* sizeof(cred.session) */;
  2881. if (code = krb5_c_random_seed(k5_context, &data)) {
  2882. com_err("libtelnet", code,
  2883. "while seeding random number generator");
  2884. return(0);
  2885. }
  2886. if (code = krb5_c_make_random_key(k5_context,
  2887. ENCTYPE_DES_CBC_RAW,
  2888. &random_key)) {
  2889. com_err("libtelnet", code,
  2890. "while creating random session key");
  2891. return(0);
  2892. }
  2893. /* the krb4 code uses ecb mode, but on a single block
  2894. with a zero ivec, ecb and cbc are the same */
  2895. k4_krbkey.enctype = ENCTYPE_DES_CBC_RAW;
  2896. k4_krbkey.length = 8;
  2897. k4_krbkey.contents = cred.session;
  2898. encdata.ciphertext.data = random_key.contents;
  2899. encdata.ciphertext.length = random_key.length;
  2900. encdata.enctype = ENCTYPE_UNKNOWN;
  2901. data.data = k4_session_key;
  2902. data.length = 8;
  2903. code = krb5_c_decrypt(k5_context, &k4_krbkey, 0, 0,
  2904. &encdata, &data);
  2905. krb5_free_keyblock_contents(k5_context, &random_key);
  2906. if (code) {
  2907. com_err("libtelnet", code, "while encrypting random key");
  2908. return(0);
  2909. }
  2910. encdata.ciphertext.data = k4_session_key;
  2911. encdata.ciphertext.length = 8;
  2912. encdata.enctype = ENCTYPE_UNKNOWN;
  2913. data.data = k4_challenge;
  2914. data.length = 8;
  2915. code = krb5_c_decrypt(k5_context, &k4_krbkey, 0, 0,
  2916. &encdata, &data);
  2917. #else /* MIT_CURRENT */
  2918. memset(k4_sched,0,sizeof(Schedule));
  2919. ckhexdump("auth_send",cred.session,8);
  2920. rc = des_key_sched(cred.session, k4_sched);
  2921. if ( rc == -1 ) {
  2922. printf("?Invalid DES key specified in credentials\r\n");
  2923. debug(F110,"auth_send",
  2924. "invalid DES Key specified in credentials",0);
  2925. } else if ( rc == -2 ) {
  2926. printf("?Weak DES key specified in credentials\r\n");
  2927. debug(F110,"auth_send",
  2928. "weak DES Key specified in credentials",0);
  2929. } else if ( rc != 0 ) {
  2930. printf("?DES Key Schedule not set by credentials\r\n");
  2931. debug(F110,"auth_send",
  2932. "DES Key Schedule not set by credentials",0);
  2933. }
  2934. ckhexdump("auth_send schedule",k4_sched,8*16);
  2935. des_set_random_generator_seed(cred.session);
  2936. do {
  2937. des_new_random_key(k4_session_key);
  2938. des_fixup_key_parity(k4_session_key);
  2939. } while ( ck_des_is_weak_key(k4_session_key) );
  2940. ckhexdump("auth_send des_new_random_key(k4_session_key)",
  2941. k4_session_key,8);
  2942. /* Decrypt the session key so that we can send it to the */
  2943. /* host as a challenge */
  2944. #ifdef NT
  2945. des_ecb_encrypt(k4_session_key, k4_session_key, k4_sched, 0);
  2946. #else /* NT */
  2947. des_ecb_encrypt(&k4_session_key, &k4_session_key, k4_sched, 0);
  2948. #endif /* NT */
  2949. ckhexdump(
  2950. "auth_send des_ecb_encrypt(k4_session_key,k4_session_key,0)",
  2951. k4_session_key,8
  2952. );
  2953. /* Prepare the result of the challenge */
  2954. /* Decrypt the session_key, add 1, and then encrypt it */
  2955. /* The result stored in k4_challenge should match the */
  2956. /* KRB4_RESPONSE value from the host. */
  2957. #ifdef NT
  2958. des_ecb_encrypt(k4_session_key, k4_challenge, k4_sched, 0);
  2959. #else /* NT */
  2960. des_ecb_encrypt(&k4_session_key, &k4_challenge, k4_sched, 0);
  2961. #endif /* NT */
  2962. ckhexdump("auth_send des_ecb_encrypt(k4_session_key,k4_challenge,0)",
  2963. k4_challenge,8);
  2964. #endif /* MIT_CURRENT */
  2965. /*
  2966. * Increment the challenge by 1, and encrypt it for
  2967. * later comparison.
  2968. */
  2969. for (i = 7; i >= 0; --i) {
  2970. register int x;
  2971. x = (unsigned int)k4_challenge[i] + 1;
  2972. k4_challenge[i] = x; /* ignore overflow */
  2973. if (x < 256) /* if no overflow, all done */
  2974. break;
  2975. }
  2976. ckhexdump("auth_send k4_challenge+1",k4_challenge,8);
  2977. #ifdef MIT_CURRENT
  2978. data.data = k4_challenge;
  2979. data.length = 8;
  2980. encdata.ciphertext.data = k4_challenge;
  2981. encdata.ciphertext.length = 8;
  2982. encdata.enctype = ENCTYPE_UNKNOWN;
  2983. if (code = krb5_c_encrypt(k5_context, &k4_krbkey, 0, 0, &data,
  2984. &encdata)) {
  2985. com_err("libtelnet", code, "while encrypting random key");
  2986. return(0);
  2987. }
  2988. #else /* MIT_CURRENT */
  2989. #ifdef NT
  2990. des_ecb_encrypt(k4_challenge, k4_challenge, k4_sched, 1);
  2991. #else /* NT */
  2992. des_ecb_encrypt(&k4_challenge, &k4_challenge, k4_sched, 1);
  2993. #endif /* NT */
  2994. ckhexdump("auth_send des_ecb_encrypt(k4_session_key,k4_challenge,1)",
  2995. k4_challenge,8);
  2996. #endif /* MIT_CURRENT */
  2997. }
  2998. #endif /* ENCRYPTION */
  2999. #endif /* REMOVE_FOR_EXPORT */
  3000. break;
  3001. #endif /* KRB4 */
  3002. #ifdef GSSAPI_KRB5
  3003. case AUTHTYPE_GSSAPI_KRB5:
  3004. for ( i=0 ; i<gss_send_tok.length ; i++ ) {
  3005. if ( ((char *)gss_send_tok.value)[i] == IAC )
  3006. iaccnt++;
  3007. }
  3008. if ( gss_send_tok.length + iaccnt + 10 < sizeof(buf) )
  3009. gss_send_tok.length = copy_for_net(&buf[7], gss_send_tok.value,
  3010. gss_send_tok.length);
  3011. else
  3012. gss_send_tok.length = 0;
  3013. sprintf(&buf[gss_send_tok.length+7], "%c%c", IAC, SE); /* safe */
  3014. if (deblog || tn_deb || debses) {
  3015. int i;
  3016. ckmakxmsg(tn_msg,TN_MSG_LEN,
  3017. "TELNET SENT SB ",TELOPT(TELOPT_AUTHENTICATION)," IS ",
  3018. AUTHTYPE_NAME(authentication_version)," ",
  3019. AUTHMODE_NAME(mode)," AUTH ",
  3020. NULL,NULL,NULL,NULL,NULL
  3021. );
  3022. tn_hex((char *)tn_msg,TN_MSG_LEN,&buf[7],gss_send_tok.length);
  3023. ckstrncat(tn_msg,"IAC SE",TN_MSG_LEN);
  3024. debug(F100,tn_msg,"",0);
  3025. if (tn_deb || debses) tn_debug(tn_msg);
  3026. }
  3027. #ifdef OS2
  3028. RequestTelnetMutex( SEM_INDEFINITE_WAIT );
  3029. #endif
  3030. ttol((CHAR *)buf, gss_send_tok.length+9);
  3031. #ifdef OS2
  3032. ReleaseTelnetMutex();
  3033. #endif
  3034. break;
  3035. #endif /* GSSAPI_KRB5 */
  3036. #ifdef KRB5
  3037. case AUTHTYPE_KERBEROS_V5:
  3038. debug(F111,"auth_send KRB5","k5_auth.length",k5_auth.length);
  3039. for ( i=0 ; i<k5_auth.length ; i++ ) {
  3040. if ( (char *)k5_auth.data[i] == IAC )
  3041. iaccnt++;
  3042. }
  3043. if ( k5_auth.length + iaccnt + 10 < sizeof(buf) ) {
  3044. k5_auth.length = copy_for_net(&buf[7],
  3045. (CHAR *)k5_auth.data,
  3046. k5_auth.length);
  3047. } else {
  3048. debug(F100,"auth_send() KRB5 auth data too large for buffer","",0);
  3049. k5_auth.length = 0;
  3050. }
  3051. sprintf((char *)&buf[k5_auth.length+7], "%c%c", IAC, SE); /* safe */
  3052. if (deblog || tn_deb || debses) {
  3053. int i;
  3054. ckmakxmsg(tn_msg,TN_MSG_LEN,
  3055. "TELNET SENT SB ",TELOPT(TELOPT_AUTHENTICATION)," IS ",
  3056. AUTHTYPE_NAME(authentication_version)," ",
  3057. AUTHMODE_NAME(mode)," AUTH ",
  3058. NULL,NULL,NULL,NULL,NULL
  3059. );
  3060. tn_hex((CHAR *)tn_msg,TN_MSG_LEN,&buf[7],k5_auth.length);
  3061. ckstrncat(tn_msg,"IAC SE",TN_MSG_LEN);
  3062. debug(F100,tn_msg,"",0);
  3063. if (tn_deb || debses) tn_debug(tn_msg);
  3064. }
  3065. #ifdef OS2
  3066. RequestTelnetMutex( SEM_INDEFINITE_WAIT );
  3067. #endif
  3068. ttol((CHAR *)buf, k5_auth.length+9);
  3069. #ifdef OS2
  3070. ReleaseTelnetMutex();
  3071. #endif
  3072. #ifdef HEIMDAL
  3073. krb5_data_free(&k5_auth);
  3074. #else /* HEIMDAL */
  3075. krb5_free_data_contents(k5_context,&k5_auth);
  3076. memset(&k5_auth,0,sizeof(krb5_data));
  3077. #endif /* HEIMDAL */
  3078. break;
  3079. #endif /* KRB5 */
  3080. }
  3081. return AUTH_SUCCESS;
  3082. }
  3083. /*
  3084. * Function: Parse authentication REPLY command
  3085. *
  3086. * Parameters:
  3087. * parsedat - the sub-command data.
  3088. *
  3089. * end_sub - index of the character in the 'parsedat' array which
  3090. * is the last byte in a sub-negotiation
  3091. *
  3092. * Returns: Kerberos error code.
  3093. */
  3094. static int
  3095. #ifdef CK_ANSIC
  3096. auth_reply(unsigned char *parsedat, int end_sub)
  3097. #else
  3098. auth_reply(parsedat,end_sub) unsigned char *parsedat; int end_sub;
  3099. #endif
  3100. {
  3101. int n = AUTH_FAILURE;
  3102. if ( parsedat[2] != authentication_version ) {
  3103. printf("Authentication version mismatch (%s [%d] != %s [%d])\r\n",
  3104. AUTHTYPE_NAME(parsedat[2]),parsedat[2],
  3105. AUTHTYPE_NAME(authentication_version),authentication_version);
  3106. auth_finished(AUTH_REJECT);
  3107. return(AUTH_FAILURE);
  3108. }
  3109. if ( parsedat[3] != (auth_how|auth_crypt|auth_fwd) ) {
  3110. printf("Authentication mode mismatch (%s != %s)\r\n",
  3111. AUTHMODE_NAME(parsedat[3]),
  3112. AUTHMODE_NAME(auth_how|auth_crypt|auth_fwd));
  3113. auth_finished(AUTH_REJECT);
  3114. return(AUTH_FAILURE);
  3115. }
  3116. #ifdef KRB4
  3117. if (authentication_version == AUTHTYPE_KERBEROS_V4)
  3118. n = k4_auth_reply(parsedat, end_sub);
  3119. #endif
  3120. #ifdef KRB5
  3121. if (authentication_version == AUTHTYPE_KERBEROS_V5)
  3122. n = k5_auth_reply(auth_how|auth_crypt|auth_fwd, parsedat, end_sub);
  3123. #endif
  3124. #ifdef CK_SRP
  3125. if (authentication_version == AUTHTYPE_SRP) {
  3126. #ifndef PRE_SRP_1_7_3
  3127. n = new_srp_reply(auth_how|auth_crypt|auth_fwd, parsedat, end_sub);
  3128. #else /* PRE_SRP_1_7_3 */
  3129. n = srp_reply(auth_how|auth_crypt|auth_fwd, parsedat, end_sub);
  3130. #endif /* PRE_SRP_1_7_3 */
  3131. }
  3132. #endif /* SRP */
  3133. #ifdef CK_SSL
  3134. if (authentication_version == AUTHTYPE_SSL)
  3135. n = ssl_reply(auth_how|auth_crypt|auth_fwd, parsedat, end_sub);
  3136. #endif /* SSL */
  3137. #ifdef NTLM
  3138. if (authentication_version == AUTHTYPE_NTLM)
  3139. n = ntlm_reply(auth_how|auth_crypt|auth_fwd, parsedat, end_sub);
  3140. #endif /* NTLM */
  3141. return n;
  3142. }
  3143. /*
  3144. * Function: Parse authentication IS command
  3145. *
  3146. * Parameters:
  3147. * parsedat - the sub-command data.
  3148. *
  3149. * end_sub - index of the character in the 'parsedat' array which
  3150. * is the last byte in a sub-negotiation
  3151. *
  3152. * Returns: Kerberos error code.
  3153. */
  3154. static int
  3155. #ifdef CK_ANSIC
  3156. auth_is(unsigned char *parsedat, int end_sub)
  3157. #else
  3158. auth_is(parsedat,end_sub) unsigned char *parsedat; int end_sub;
  3159. #endif
  3160. {
  3161. int n = AUTH_FAILURE;
  3162. if ( parsedat[2] == AUTHTYPE_NULL ) {
  3163. auth_finished(AUTH_REJECT);
  3164. return(AUTH_FAILURE);
  3165. }
  3166. /*
  3167. * If CLIENT_CHOOSE_ONCE is selected the server will not allow the
  3168. * client to switch to an alternate authentication method if the one
  3169. * it originally selected fails. (ie, if the host's SRP parameters
  3170. * are invalid.) However, I think this is a bit of a security risk
  3171. * since allowing that functionality means that it is impossible to
  3172. * detect if an attack is being carried out on
  3173. */
  3174. #define CLIENT_CHOOSE_ONCE
  3175. #ifdef CLIENT_CHOOSE_ONCE
  3176. if ( authentication_version == AUTHTYPE_AUTO )
  3177. #endif /* CLIENT_CHOOSE_ONCE */
  3178. {
  3179. /* this block of code needs to check the initial parameters */
  3180. /* to ensure that those returned match one of the sets that */
  3181. /* were sent to the client in the first place. */
  3182. int i=0;
  3183. for ( i=4; str_request[i] != IAC ; i+=2) {
  3184. if (str_request[i] == parsedat[2] &&
  3185. str_request[i+1] == parsedat[3])
  3186. break;
  3187. }
  3188. if ( str_request[i] == IAC ) {
  3189. printf("Invalid authentication type pair (%s,%s)\r\n",
  3190. AUTHTYPE_NAME(parsedat[2]),
  3191. AUTHMODE_NAME(parsedat[3]));
  3192. auth_finished(AUTH_REJECT);
  3193. return(AUTH_FAILURE);
  3194. }
  3195. if (authentication_version != parsedat[2]) {
  3196. authentication_version = parsedat[2];
  3197. auth_how = (parsedat[3] & AUTH_HOW_MASK);
  3198. auth_crypt = (parsedat[3] & AUTH_ENCRYPT_MASK);
  3199. auth_fwd = (parsedat[3] & INI_CRED_FWD_MASK);
  3200. debug(F111,"auth_is","authentication_version",
  3201. authentication_version);
  3202. debug(F111,"auth_is","auth_how",auth_how);
  3203. debug(F111,"auth_is","auth_crypt",auth_crypt);
  3204. debug(F111,"auth_is","auth_fwd",auth_fwd);
  3205. }
  3206. }
  3207. #ifdef CLIENT_CHOOSE_ONCE
  3208. if ( parsedat[2] != authentication_version ) {
  3209. printf("Authentication version mismatch (%s [%d] != %s [%d])\r\n",
  3210. AUTHTYPE_NAME(parsedat[2]),parsedat[2],
  3211. AUTHTYPE_NAME(authentication_version),authentication_version);
  3212. auth_finished(AUTH_REJECT);
  3213. return(AUTH_FAILURE);
  3214. }
  3215. if ( parsedat[3] != (auth_how|auth_crypt|auth_fwd) ) {
  3216. printf("Authentication mode mismatch (%s != %s)\r\n",
  3217. AUTHMODE_NAME(parsedat[3]),
  3218. AUTHMODE_NAME(auth_how|auth_crypt|auth_fwd));
  3219. auth_finished(AUTH_REJECT);
  3220. return(AUTH_FAILURE);
  3221. }
  3222. #endif /* CLIENT_CHOOSE_ONCE */
  3223. switch (authentication_version) {
  3224. #ifdef KRB4
  3225. case AUTHTYPE_KERBEROS_V4:
  3226. n = k4_auth_is(parsedat, end_sub);
  3227. break;
  3228. #endif
  3229. #ifdef KRB5
  3230. case AUTHTYPE_KERBEROS_V5:
  3231. n = k5_auth_is(parsedat[3],parsedat, end_sub);
  3232. break;
  3233. #endif
  3234. #ifdef CK_SRP
  3235. case AUTHTYPE_SRP:
  3236. #ifndef PRE_SRP_1_7_3
  3237. n = new_srp_is(parsedat[3], parsedat, end_sub);
  3238. #else /* PRE_SRP_1_7_3 */
  3239. n = srp_is(parsedat[3], parsedat, end_sub);
  3240. #endif /* PRE_SRP_1_7_3 */
  3241. break;
  3242. #endif /* SRP */
  3243. #ifdef CK_SSL
  3244. case AUTHTYPE_SSL:
  3245. TELOPT_ME_MODE(TELOPT_ENCRYPTION) = TN_NG_RF;
  3246. TELOPT_U_MODE(TELOPT_ENCRYPTION) = TN_NG_RF;
  3247. n = ssl_is(parsedat, end_sub);
  3248. break;
  3249. #endif /* SSL */
  3250. #ifdef NTLM
  3251. case AUTHTYPE_NTLM:
  3252. TELOPT_ME_MODE(TELOPT_ENCRYPTION) = TN_NG_RF;
  3253. TELOPT_U_MODE(TELOPT_ENCRYPTION) = TN_NG_RF;
  3254. n = ntlm_is(parsedat, end_sub);
  3255. break;
  3256. #endif /* NTLM */
  3257. case AUTHTYPE_NULL:
  3258. default:
  3259. n = AUTH_FAILURE;
  3260. }
  3261. debug(F111,"auth_is","n",n);
  3262. return n;
  3263. }
  3264. /*
  3265. * Function: Parse authentication NAME command
  3266. *
  3267. * Parameters:
  3268. * parsedat - the sub-command data.
  3269. *
  3270. * end_sub - index of the character in the 'parsedat' array which
  3271. * is the last byte in a sub-negotiation
  3272. *
  3273. * Returns: Kerberos error code.
  3274. */
  3275. static int
  3276. #ifdef CK_ANSIC
  3277. auth_name(unsigned char *parsedat, int end_sub)
  3278. #else
  3279. auth_name(parsedat,end_sub) unsigned char *parsedat; int end_sub;
  3280. #endif
  3281. {
  3282. int len = (end_sub-2) > 63 ? 63 : (end_sub-2);
  3283. if ( len > 0 && (len + 1) < sizeof(szUserNameRequested)) {
  3284. memcpy(szUserNameRequested,&parsedat[2],len); /* safe */
  3285. szUserNameRequested[len] = '\0';
  3286. } else
  3287. szUserNameRequested[0] = '\0';
  3288. debug(F111,"auth_name szUserNameRequested",szUserNameRequested,len);
  3289. return(AUTH_SUCCESS);
  3290. }
  3291. /*
  3292. * Function: Parse the athorization sub-options and reply.
  3293. *
  3294. * Parameters:
  3295. * parsedat - sub-option string to parse.
  3296. *
  3297. * end_sub - last charcter position in parsedat.
  3298. */
  3299. int
  3300. auth_parse(unsigned char *parsedat, int end_sub)
  3301. {
  3302. int rc = AUTH_FAILURE;
  3303. switch (parsedat[1]) {
  3304. case TELQUAL_SEND:
  3305. rc = auth_send(parsedat, end_sub);
  3306. break;
  3307. case TELQUAL_REPLY:
  3308. rc= auth_reply(parsedat, end_sub);
  3309. break;
  3310. case TELQUAL_IS:
  3311. rc = auth_is(parsedat, end_sub);
  3312. break;
  3313. case TELQUAL_NAME:
  3314. rc = auth_name(parsedat, end_sub);
  3315. break;
  3316. }
  3317. debug(F111,"auth_parse","rc",rc);
  3318. return(rc);
  3319. }
  3320. /*
  3321. * Function: Initialization routine called kstream encryption system.
  3322. *
  3323. * Parameters:
  3324. * data - user data.
  3325. */
  3326. int
  3327. #ifdef CK_ANSIC
  3328. auth_init(kstream ks)
  3329. #else
  3330. auth_init(ks) kstream_ptr ks;
  3331. #endif
  3332. {
  3333. #ifdef FORWARD
  3334. forwarded_tickets = 0; /* were tickets forwarded? */
  3335. #endif /* FORWARD */
  3336. #ifdef CK_ENCRYPTION
  3337. encrypt_init(ks,cx_type);
  3338. #endif
  3339. return 0;
  3340. }
  3341. /*
  3342. * Function: Destroy routine called kstream encryption system.
  3343. *
  3344. * Parameters:
  3345. * data - user data.
  3346. */
  3347. VOID
  3348. #ifdef CK_ANSIC
  3349. auth_destroy(void)
  3350. #else
  3351. auth_destroy()
  3352. #endif
  3353. {
  3354. }
  3355. /*
  3356. * Function: Callback to encrypt a block of characters
  3357. *
  3358. * Parameters:
  3359. * out - return as pointer to converted buffer.
  3360. *
  3361. * in - the buffer to convert
  3362. *
  3363. * Returns: number of characters converted.
  3364. */
  3365. int
  3366. #ifdef CK_ANSIC
  3367. auth_encrypt(struct kstream_data_block *out,
  3368. struct kstream_data_block *in)
  3369. #else
  3370. auth_encrypt(out,in)
  3371. struct kstream_data_block *out; struct kstream_data_block *in;
  3372. #endif
  3373. {
  3374. out->ptr = in->ptr;
  3375. out->length = in->length;
  3376. return(out->length);
  3377. }
  3378. /*
  3379. * Function: Callback to decrypt a block of characters
  3380. *
  3381. * Parameters:
  3382. * out - return as pointer to converted buffer.
  3383. *
  3384. * in - the buffer to convert
  3385. *
  3386. * Returns: number of characters converted.
  3387. */
  3388. int
  3389. #ifdef CK_ANSIC
  3390. auth_decrypt(struct kstream_data_block *out,
  3391. struct kstream_data_block *in)
  3392. #else
  3393. auth_decrypt(out,in)
  3394. struct kstream_data_block *out; struct kstream_data_block *in;
  3395. #endif
  3396. {
  3397. out->ptr = in->ptr;
  3398. out->length = in->length;
  3399. return(out->length);
  3400. }
  3401. #ifdef KRB4
  3402. #ifdef NT
  3403. void
  3404. ck_krb4_debug(int x)
  3405. {
  3406. set_krb_debug(x);
  3407. set_krb_ap_req_debug(x);
  3408. }
  3409. #endif /* NT */
  3410. int
  3411. ck_krb4_autoget_TGT(char * realm)
  3412. {
  3413. extern struct krb_op_data krb_op;
  3414. extern struct krb4_init_data krb4_init;
  3415. char passwd[PWD_SZ];
  3416. char prompt[256];
  3417. char * saverealm=NULL;
  3418. int rc = -1;
  3419. extern char * k4prprompt;
  3420. extern char * k4pwprompt;
  3421. ini_kerb(); /* Place defaults in above structs */
  3422. passwd[0] = '\0';
  3423. if ( krb4_init.principal == NULL ||
  3424. krb4_init.principal[0] == '\0') {
  3425. int ok = uq_txt(NULL,
  3426. k4prprompt && k4prprompt[0] ?
  3427. k4prprompt :
  3428. "Kerberos 4 Principal: ",
  3429. 2, NULL, passwd,PWD_SZ-1, NULL, DEFAULT_UQ_TIMEOUT);
  3430. if ( ok && passwd[0] )
  3431. makestr(&krb4_init.principal,passwd);
  3432. else
  3433. return(0);
  3434. }
  3435. /* Save realm in init structure so it can be restored */
  3436. if ( realm ) {
  3437. saverealm = krb4_init.realm;
  3438. krb4_init.realm = realm;
  3439. }
  3440. if ( passwd[0] || !(pwbuf[0] && pwflg) ) {
  3441. int ok;
  3442. if ( k4pwprompt && k4pwprompt[0] &&
  3443. (strlen(k4pwprompt) + strlen(krb4_init.principal) +
  3444. strlen(krb4_init.realm) - 4) < sizeof(prompt)) {
  3445. sprintf(prompt,k4pwprompt,krb4_init.principal,krb4_init.realm);
  3446. } else
  3447. ckmakxmsg(prompt,sizeof(prompt),
  3448. "Kerberos 4 Password for ",krb4_init.principal,"@",
  3449. krb4_init.realm,": ",
  3450. NULL,NULL,NULL,NULL,NULL,NULL,NULL);
  3451. ok = uq_txt(NULL,prompt,2,NULL,passwd,PWD_SZ-1,NULL,
  3452. DEFAULT_UQ_TIMEOUT);
  3453. if ( !ok )
  3454. passwd[0] = '\0';
  3455. } else {
  3456. ckstrncpy(passwd,pwbuf,sizeof(passwd));
  3457. #ifdef OS2
  3458. if ( pwcrypt )
  3459. ck_encrypt((char *)passwd);
  3460. #endif /* OS2 */
  3461. }
  3462. if ( passwd[0] ) {
  3463. makestr(&krb4_init.password,passwd);
  3464. rc = ck_krb4_initTGT(&krb_op, &krb4_init);
  3465. free(krb4_init.password);
  3466. krb4_init.password = NULL;
  3467. }
  3468. krb4_init.password = NULL;
  3469. memset(passwd,0,PWD_SZ);
  3470. /* restore realm to init structure if needed */
  3471. if ( saverealm )
  3472. krb4_init.realm = saverealm;
  3473. return(rc == 0);
  3474. }
  3475. char *
  3476. ck_krb4_realmofhost(char *host)
  3477. {
  3478. return (char *)krb_realmofhost(host);
  3479. }
  3480. /*
  3481. *
  3482. * K4_auth_send - gets authentication bits we need to send to KDC.
  3483. *
  3484. * Result is left in auth
  3485. *
  3486. * Returns: 0 on failure, 1 on success
  3487. */
  3488. static int
  3489. #ifdef CK_ANSIC
  3490. k4_auth_send(void)
  3491. #else
  3492. k4_auth_send()
  3493. #endif
  3494. {
  3495. int r=0; /* Return value */
  3496. char instance[INST_SZ+1]="";
  3497. char *realm=NULL;
  3498. char tgt[4*REALM_SZ+1];
  3499. memset(instance, 0, sizeof(instance));
  3500. #ifdef COMMENT
  3501. /* we only need to call krb_get_phost if the hostname */
  3502. /* is not fully qualified. But we have already done */
  3503. /* this in netopen() call. This will save a round of */
  3504. /* DNS queries. */
  3505. debug(F110,"k4_auth_send","krb_get_phost",0);
  3506. if (realm = (char *)krb_get_phost(szHostName)) {
  3507. ckstrncpy(instance, realm, INST_SZ);
  3508. }
  3509. #else /* COMMENT */
  3510. {
  3511. char *p;
  3512. ckstrncpy(instance, szHostName, INST_SZ);
  3513. for ( p=instance; *p && *p != '.' ; p++ );
  3514. *p = '\0';
  3515. }
  3516. #endif /* COMMENT */
  3517. debug(F110,"k4_auth_send","krb_get_realmofhost",0);
  3518. realm = (char *)krb_realmofhost(szHostName);
  3519. if (!realm) {
  3520. strcpy(strTmp, "Can't find realm for host \"");
  3521. ckstrncat(strTmp, szHostName,AUTHTMPBL);
  3522. ckstrncat(strTmp, "\"",AUTHTMPBL);
  3523. printf("?Kerberos 4 error: %s\r\n",strTmp);
  3524. krb4_errno = r;
  3525. makestr(&krb4_errmsg,strTmp);
  3526. return(0);
  3527. }
  3528. ckmakmsg(tgt,sizeof(tgt),"krbtgt.",realm,"@",realm);
  3529. r = ck_krb4_tkt_isvalid(tgt);
  3530. if ( r <= 0 && krb4_autoget )
  3531. ck_krb4_autoget_TGT(realm);
  3532. debug(F110,"k4_auth_send","krb_mk_req",0);
  3533. r = krb_mk_req(&k4_auth, krb4_d_srv ? krb4_d_srv : KRB4_SERVICE_NAME,
  3534. instance, realm, 0);
  3535. if (r == 0) {
  3536. debug(F110,"k4_auth_send","krb_get_cred",0);
  3537. r = krb_get_cred(krb4_d_srv ? krb4_d_srv : KRB4_SERVICE_NAME,
  3538. instance, realm, &cred);
  3539. if (r)
  3540. debug(F111,"k4_auth_send","krb_get_cred() failed",r);
  3541. }
  3542. else
  3543. debug(F111,"k4_auth_send","krb_mk_req() failed",r);
  3544. if (r) {
  3545. strcpy(strTmp, "Can't get \"");
  3546. ckstrncat(strTmp,
  3547. krb4_d_srv ? krb4_d_srv : KRB4_SERVICE_NAME,AUTHTMPBL);
  3548. if (instance[0] != 0) {
  3549. ckstrncat(strTmp, ".",AUTHTMPBL);
  3550. ckstrncat(strTmp, instance,AUTHTMPBL);
  3551. }
  3552. ckstrncat(strTmp, "@",AUTHTMPBL);
  3553. ckstrncat(strTmp, realm,AUTHTMPBL);
  3554. ckstrncat(strTmp, "\" ticket\r\n ",AUTHTMPBL);
  3555. ckstrncat(strTmp, (char *)krb_get_err_text_entry(r),AUTHTMPBL);
  3556. debug(F111,"k4_auth_send",(char *)krb_get_err_text_entry(r),r);
  3557. printf("?Kerberos 4 error: %s\r\n",strTmp);
  3558. krb4_errno = r;
  3559. makestr(&krb4_errmsg,krb_get_err_text_entry(krb4_errno));
  3560. return(0);
  3561. }
  3562. #ifdef OS2
  3563. if ( !szUserName[0] || !stricmp(szUserName,cred.pname) ) {
  3564. ckstrncpy(szUserName, cred.pname, UIDBUFLEN);
  3565. }
  3566. #endif /* OS2 */
  3567. krb4_errno = r;
  3568. makestr(&krb4_errmsg,krb_get_err_text_entry(krb4_errno));
  3569. debug(F110,"k4_auth_send",krb4_errmsg,0);
  3570. return(1);
  3571. }
  3572. /*
  3573. * Function: K4 parse authentication reply command
  3574. *
  3575. * Parameters:
  3576. * parsedat - the sub-command data.
  3577. *
  3578. * end_sub - index of the character in the 'parsedat' array which
  3579. * is the last byte in a sub-negotiation
  3580. *
  3581. * Returns: Kerberos error code.
  3582. */
  3583. static int
  3584. #ifdef CK_ANSIC
  3585. k4_auth_reply(unsigned char *parsedat, int end_sub)
  3586. #else
  3587. k4_auth_reply(parsedat,end_sub) unsigned char *parsedat; int end_sub;
  3588. #endif
  3589. {
  3590. #ifdef CK_ENCRYPTION
  3591. Session_Key skey;
  3592. #ifdef MIT_CURRENT
  3593. krb5_data kdata;
  3594. krb5_enc_data encdata;
  3595. krb5_error_code code;
  3596. #endif /* MIT_CURRENT */
  3597. #endif
  3598. time_t t;
  3599. int x;
  3600. int i;
  3601. if (end_sub < 4 || parsedat[2] != AUTHTYPE_KERBEROS_V4) {
  3602. auth_finished(AUTH_REJECT);
  3603. return AUTH_FAILURE;
  3604. }
  3605. if (parsedat[4] == KRB_REJECT) {
  3606. strTmp[0] = 0;
  3607. for (i = 5; i <= end_sub; i++) {
  3608. if (parsedat[i] == IAC)
  3609. break;
  3610. strTmp[i-5] = parsedat[i];
  3611. strTmp[i-4] = 0;
  3612. }
  3613. if (!strTmp[0])
  3614. strcpy(strTmp, "Authentication rejected by remote machine!");
  3615. printf("Kerberos V4 authentication failed!\r\n%s\r\n",strTmp);
  3616. krb4_errno = -1;
  3617. makestr(&krb4_errmsg,strTmp);
  3618. auth_finished(AUTH_REJECT);
  3619. return AUTH_FAILURE;
  3620. }
  3621. if (parsedat[4] == KRB_ACCEPT) {
  3622. int net_len;
  3623. if ((parsedat[3] & AUTH_HOW_MASK) == AUTH_HOW_ONE_WAY) {
  3624. ckmakmsg(strTmp,sizeof(strTmp),"Kerberos V4 accepts you as ",
  3625. szUserName,NULL,NULL);
  3626. printf("%s\r\n",strTmp);
  3627. accept_complete = 1;
  3628. krb4_errno = 0;
  3629. makestr(&krb4_errmsg,strTmp);
  3630. auth_finished(AUTH_USER);
  3631. return AUTH_SUCCESS;
  3632. }
  3633. if ((parsedat[3] & AUTH_HOW_MASK) != AUTH_HOW_MUTUAL) {
  3634. printf("Kerberos V4 authentication failed!\r\n");
  3635. ckstrncpy(strTmp,
  3636. "Kerberos V4 accepted you, but didn't provide mutual authentication",
  3637. sizeof(strTmp));
  3638. printf("%s\r\n",strTmp);
  3639. krb4_errno = -1;
  3640. makestr(&krb4_errmsg,strTmp);
  3641. auth_finished(AUTH_REJECT);
  3642. return AUTH_FAILURE;
  3643. }
  3644. #ifndef REMOVE_FOR_EXPORT
  3645. #ifdef CK_ENCRYPTION
  3646. SendK4AuthSB(KRB4_CHALLENGE,k4_session_key,sizeof(k4_session_key));
  3647. /* We have sent the decrypted session key to the host as a challenge */
  3648. /* now encrypt it to restore it to its original valid DES key value */
  3649. #ifdef MIT_CURRENT
  3650. kdata.data = k4_session_key;
  3651. kdata.length = 8;
  3652. encdata.ciphertext.data = k4_session_key;
  3653. encdata.ciphertext.length = 8;
  3654. encdata.enctype = ENCTYPE_UNKNOWN;
  3655. if (code = krb5_c_encrypt(k5_context, &k4_krbkey,
  3656. 0, 0, &kdata, &encdata)) {
  3657. com_err("k4_auth_reply", code,
  3658. "while encrypting session_key");
  3659. auth_finished(AUTH_REJECT);
  3660. return AUTH_FAILURE;
  3661. }
  3662. #else /* MIT_CURRENT */
  3663. #ifdef NT
  3664. des_ecb_encrypt(k4_session_key, k4_session_key, k4_sched, 1);
  3665. #else /* NT */
  3666. des_ecb_encrypt(&k4_session_key, &k4_session_key, k4_sched, 1);
  3667. #endif /* NT */
  3668. ckhexdump(
  3669. "k4_auth_reply des_ecb_encrypt(k4_session_key,k4_session_key,1)",
  3670. k4_session_key,
  3671. 8
  3672. );
  3673. #endif /* MIT_CURRENT */
  3674. #ifdef CK_SSL
  3675. if (!(ssl_active_flag || tls_active_flag))
  3676. #endif /* CK_SSL */
  3677. {
  3678. /* And then use it to configure the encryption state machine. */
  3679. skey.type = SK_DES;
  3680. skey.length = 8;
  3681. skey.data = k4_session_key;
  3682. encrypt_session_key(&skey, AUTH_CLIENT_TO_SERVER);
  3683. }
  3684. #endif /* ENCRYPTION */
  3685. #endif /* REMOVE_FOR_EXPORT */
  3686. accept_complete = 1;
  3687. ckmakmsg(strTmp,sizeof(strTmp),
  3688. "Kerberos V4 accepts you as ",szUserName,NULL,NULL);
  3689. printf("%s\r\n",strTmp);
  3690. krb4_errno = 0;
  3691. makestr(&krb4_errmsg,strTmp);
  3692. auth_finished(AUTH_USER);
  3693. return AUTH_SUCCESS;
  3694. }
  3695. if (parsedat[4] == KRB4_RESPONSE) {
  3696. if (end_sub < 12) {
  3697. auth_finished(AUTH_REJECT);
  3698. return AUTH_FAILURE;
  3699. }
  3700. ckhexdump("KRB4_RESPONSE &parsedat[5]",&parsedat[5],8);
  3701. #ifdef CK_ENCRYPTION
  3702. ckhexdump("KRB4_RESPONSE k4_challenge",k4_challenge,8);
  3703. /* The datablock returned from the host should match the value */
  3704. /* we stored in k4_challenge. */
  3705. if (memcmp(&parsedat[5], k4_challenge, sizeof(k4_challenge)) != 0) {
  3706. printf("Kerberos V4 authentication failed!\r\n%s\r\n",
  3707. "Remote machine is being impersonated!");
  3708. krb4_errno = -1;
  3709. makestr(&krb4_errmsg,"Remote machine is being impersonated!");
  3710. auth_finished(AUTH_REJECT);
  3711. return AUTH_FAILURE;
  3712. }
  3713. #else /* ENCRYPTION */
  3714. makestr(&krb4_errmsg,"Kermit built without support for encryption.");
  3715. return AUTH_FAILURE;
  3716. #endif /* ENCRYPTION */
  3717. mutual_complete = 1;
  3718. ckstrncpy(strTmp,"Remote machine has been mutually authenticated",
  3719. sizeof(strTmp));
  3720. printf("%s\r\n",strTmp);
  3721. krb4_errno = 0;
  3722. makestr(&krb4_errmsg,strTmp);
  3723. auth_finished(AUTH_USER);
  3724. return AUTH_SUCCESS;
  3725. }
  3726. auth_finished(AUTH_REJECT);
  3727. return AUTH_FAILURE;
  3728. }
  3729. /*
  3730. * Function: K4 parse authentication IS command
  3731. *
  3732. * Parameters:
  3733. * parsedat - the sub-command data.
  3734. *
  3735. * end_sub - index of the character in the 'parsedat' array which
  3736. * is the last byte in a sub-negotiation
  3737. *
  3738. * Returns: Kerberos error code.
  3739. */
  3740. static int
  3741. #ifdef CK_ANSIC
  3742. k4_auth_is(unsigned char *parsedat, int end_sub)
  3743. #else
  3744. k4_auth_is(parsedat,end_sub) unsigned char *parsedat; int end_sub;
  3745. #endif
  3746. {
  3747. #ifdef CK_ENCRYPTION
  3748. Session_Key skey;
  3749. #ifdef MIT_CURRENT
  3750. Block datablock, tmpkey;
  3751. krb5_data kdata;
  3752. krb5_enc_data encdata;
  3753. krb5_error_code code;
  3754. #else /* MIT_CURRENT */
  3755. Block datablock;
  3756. #endif /* MIT_CURRENT */
  3757. #endif /* ENCRYPTION */
  3758. char realm[REALM_SZ+1];
  3759. char instance[INST_SZ];
  3760. int r = 0;
  3761. char * data = &parsedat[5];
  3762. int cnt = end_sub - 5;
  3763. extern char myipaddr[];
  3764. struct hostent *host;
  3765. struct in_addr inaddr;
  3766. int i;
  3767. if (end_sub < 4 || parsedat[2] != AUTHTYPE_KERBEROS_V4) {
  3768. debug(F110,"k4_auth_is","Not kerberos v4",0);
  3769. auth_finished(AUTH_REJECT);
  3770. return AUTH_FAILURE;
  3771. }
  3772. switch (parsedat[4]) {
  3773. case KRB_AUTH:
  3774. debug(F110,"k4_auth_is","KRB_AUTH",0);
  3775. ckstrncpy(realm,ck_krb4_getrealm(),REALM_SZ+1);
  3776. if (realm[0] == '\0') {
  3777. SendK4AuthSB(KRB_REJECT, (void *)"No local V4 Realm.", -1);
  3778. printf("\r\n? Kerberos 4 - No Local Realm\r\n");
  3779. debug(F110,"k4_auth_is","No local realm",0);
  3780. krb4_errno = -1;
  3781. makestr(&krb4_errmsg,"No local realm");
  3782. auth_finished(AUTH_REJECT);
  3783. return AUTH_FAILURE;
  3784. }
  3785. debug(F110,"k4_auth_is",realm,0);
  3786. if ( cnt < sizeof(k4_auth.dat) ) {
  3787. k4_auth.length = cnt;
  3788. memcpy((void *)k4_auth.dat, (void *)data, k4_auth.length);
  3789. } else
  3790. k4_auth.length = 0;
  3791. ckhexdump("k4_auth.dat",k4_auth.dat, k4_auth.length);
  3792. /* Get Instance */
  3793. inaddr.s_addr = inet_addr(myipaddr);
  3794. host = gethostbyaddr((unsigned char *)&inaddr,4,PF_INET);
  3795. if ( host ) {
  3796. #ifdef HADDRLIST
  3797. host = ck_copyhostent(host);
  3798. #endif /* HADDRLIST */
  3799. ckstrncpy(instance,host->h_name,INST_SZ);
  3800. for ( i=0;i<INST_SZ;i++ ) {
  3801. if ( instance[i] == '.' )
  3802. instance[i] = '\0';
  3803. else
  3804. instance[i] = tolower(instance[i]);
  3805. }
  3806. } else {
  3807. instance[0] = '*';
  3808. instance[1] = 0;
  3809. }
  3810. if (r = krb_rd_req(&k4_auth,
  3811. krb4_d_srv ? krb4_d_srv : KRB4_SERVICE_NAME,
  3812. instance, 0, &k4_adat, k4_keytab)) {
  3813. ckhexdump("k4_adat", &k4_adat, sizeof(AUTH_DAT));
  3814. krb_kntoln(&k4_adat, k4_name);
  3815. ckmakmsg(strTmp,sizeof(strTmp),
  3816. "Kerberos failed him as ", k4_name,NULL,NULL);
  3817. printf("%s\r\n",strTmp);
  3818. krb4_errno = r;
  3819. makestr(&krb4_errmsg,strTmp);
  3820. SendK4AuthSB(KRB_REJECT, (void *)krb_get_err_text_entry(r), -1);
  3821. auth_finished(AUTH_REJECT);
  3822. return AUTH_FAILURE;
  3823. }
  3824. #ifdef CK_ENCRYPTION
  3825. memcpy((void *)k4_session_key, (void *)k4_adat.session,
  3826. sizeof(Block)); /* safe */
  3827. ckhexdump("k4_auth_is k4_session_key",k4_session_key,sizeof(Block));
  3828. #endif /* ENCRYPTION */
  3829. krb_kntoln(&k4_adat, k4_name);
  3830. ckstrncpy(szUserNameAuthenticated,k4_name,UIDBUFLEN);
  3831. if (szUserNameRequested && !kuserok(&k4_adat, k4_name)) {
  3832. SendK4AuthSB(KRB_ACCEPT, (void *)0, 0);
  3833. if ( !strcmp(k4_name,szUserNameRequested) )
  3834. auth_finished(AUTH_VALID);
  3835. else
  3836. auth_finished(AUTH_USER);
  3837. accept_complete = 1;
  3838. }
  3839. else {
  3840. SendK4AuthSB(KRB_REJECT,
  3841. (void *)"user is not authorized", -1);
  3842. auth_finished(AUTH_REJECT);
  3843. krb4_errno = r;
  3844. makestr(&krb4_errmsg,"user is not authorized");
  3845. return(AUTH_FAILURE);
  3846. }
  3847. break;
  3848. case KRB4_CHALLENGE:
  3849. debug(F110,"k4_auth_is","KRB_CHALLENGE",0);
  3850. #ifndef CK_ENCRYPTION
  3851. SendK4AuthSB(KRB4_RESPONSE, (void *)0, 0);
  3852. #else /* ENCRYPTION */
  3853. if (!VALIDKEY(k4_session_key)) {
  3854. /*
  3855. * We don't have a valid session key, so just
  3856. * send back a response with an empty session
  3857. * key.
  3858. */
  3859. SendK4AuthSB(KRB4_RESPONSE, (void *)0, 0);
  3860. mutual_complete = 1;
  3861. break;
  3862. }
  3863. /*
  3864. * Initialize the random number generator since it's
  3865. * used later on by the encryption routine.
  3866. */
  3867. #ifdef MIT_CURRENT
  3868. kdata.data = k4_session_key;
  3869. kdata.length = 8;
  3870. if (code = krb5_c_random_seed(k5_context, &kdata)) {
  3871. com_err("k4_auth_is", code,
  3872. "while seeding random number generator");
  3873. auth_finished(AUTH_REJECT);
  3874. return AUTH_FAILURE;
  3875. }
  3876. memcpy((void *)datablock, (void *)data, sizeof(Block)); /* safe */
  3877. /*
  3878. * Take the received encrypted challenge, and encrypt
  3879. * it again to get a unique session_key for the
  3880. * ENCRYPT option.
  3881. */
  3882. k4_krbkey.enctype = ENCTYPE_DES_CBC_RAW;
  3883. k4_krbkey.length = 8;
  3884. k4_krbkey.contents = k4_session_key;
  3885. kdata.data = datablock;
  3886. kdata.length = 8;
  3887. encdata.ciphertext.data = tmpkey;
  3888. encdata.ciphertext.length = 8;
  3889. encdata.enctype = ENCTYPE_UNKNOWN;
  3890. if (code = krb5_c_encrypt(k5_context, &k4_krbkey, 0, 0,
  3891. &kdata, &encdata)) {
  3892. com_err("k4_auth_is", code, "while encrypting random key");
  3893. auth_finished(AUTH_REJECT);
  3894. return AUTH_FAILURE;
  3895. }
  3896. #ifdef CK_SSL
  3897. if (!(ssl_active_flag || tls_active_flag))
  3898. #endif /* CK_SSL */
  3899. {
  3900. skey.type = SK_DES;
  3901. skey.length = 8;
  3902. skey.data = tmpkey;
  3903. encrypt_session_key(&skey, AUTH_SERVER_TO_CLIENT);
  3904. }
  3905. /*
  3906. * Now decrypt the received encrypted challenge,
  3907. * increment by one, re-encrypt it and send it back.
  3908. */
  3909. encdata.ciphertext.data = datablock;
  3910. encdata.ciphertext.length = 8;
  3911. encdata.enctype = ENCTYPE_UNKNOWN;
  3912. kdata.data = k4_challenge;
  3913. kdata.length = 8;
  3914. if (code = krb5_c_decrypt(k5_context, &k4_krbkey, 0, 0,
  3915. &encdata, &kdata)) {
  3916. com_err("k4_auth_is", code, "while decrypting challenge");
  3917. auth_finished(AUTH_REJECT);
  3918. return AUTH_FAILURE;
  3919. }
  3920. #else /* MIT_CURRENT */
  3921. des_set_random_generator_seed(k4_session_key);
  3922. r = des_key_sched(k4_session_key, k4_sched);
  3923. if ( r == -1 ) {
  3924. printf("?Invalid DES key specified in credentials\r\n");
  3925. debug(F110,"auth_is CHALLENGE",
  3926. "invalid DES Key specified in credentials",0);
  3927. } else if ( r == -2 ) {
  3928. printf("?Weak DES key specified in credentials\r\n");
  3929. debug(F110,"auth_is CHALLENGE",
  3930. "weak DES Key specified in credentials",0);
  3931. } else if ( r != 0 ) {
  3932. printf("?DES Key Schedule not set by credentials\r\n");
  3933. debug(F110,"auth_is CHALLENGE",
  3934. "DES Key Schedule not set by credentials",0);
  3935. }
  3936. ckhexdump("auth_is schedule",k4_sched,8*16);
  3937. memcpy((void *)datablock, (void *)data, sizeof(Block)); /* safe */
  3938. ckhexdump("auth_is challege",datablock,sizeof(Block));
  3939. /*
  3940. * Take the received encrypted challenge, and encrypt
  3941. * it again to get a unique k4_session_key for the
  3942. * ENCRYPT option.
  3943. */
  3944. #ifdef NT
  3945. des_ecb_encrypt(datablock, k4_session_key, k4_sched, 1);
  3946. #else /* NT */
  3947. des_ecb_encrypt(&datablock, &k4_session_key, k4_sched, 1);
  3948. #endif /* NT */
  3949. ckhexdump("auth_is des_ecb_encrypt(datablock,k4_session_key,1)",
  3950. k4_session_key,8);
  3951. #ifdef CK_SSL
  3952. if (!(ssl_active_flag || tls_active_flag))
  3953. #endif /* CK_SSL */
  3954. {
  3955. skey.type = SK_DES;
  3956. skey.length = 8;
  3957. skey.data = k4_session_key;
  3958. encrypt_session_key(&skey, AUTH_SERVER_TO_CLIENT);
  3959. }
  3960. /*
  3961. * Now decrypt the received encrypted challenge,
  3962. * increment by one, re-encrypt it and send it back.
  3963. */
  3964. #ifdef NT
  3965. des_ecb_encrypt(datablock, k4_challenge, k4_sched, 0);
  3966. #else /* NT */
  3967. des_ecb_encrypt(&datablock, &k4_challenge, k4_sched, 0);
  3968. #endif /* NT */
  3969. ckhexdump("auth_is des_ecb_encrypt(datablock,k4_challenge,0)",
  3970. k4_session_key,8);
  3971. #endif /* MIT_CURRENT */
  3972. for (r = 7; r >= 0; r--) {
  3973. register int t;
  3974. t = (unsigned int)k4_challenge[r] + 1;
  3975. k4_challenge[r] = t; /* ignore overflow */
  3976. if (t < 256) /* if no overflow, all done */
  3977. break;
  3978. }
  3979. ckhexdump("auth_is k4_challenge+1",k4_challenge,8);
  3980. #ifdef MIT_CURRENT
  3981. kdata.data = k4_challenge;
  3982. kdata.length = 8;
  3983. encdata.ciphertext.data = k4_challenge;
  3984. encdata.ciphertext.length = 8;
  3985. encdata.enctype = ENCTYPE_UNKNOWN;
  3986. if (code = krb5_c_encrypt(k5_context, &k4_krbkey, 0, 0,
  3987. &kdata, &encdata)) {
  3988. com_err("k4_auth_is", code, "while decrypting challenge");
  3989. auth_finished(AUTH_REJECT);
  3990. return AUTH_FAILURE;
  3991. }
  3992. #else /* MIT_CURRENT */
  3993. #ifdef NT
  3994. des_ecb_encrypt(k4_challenge, k4_challenge, k4_sched, 1);
  3995. #else /* NT */
  3996. des_ecb_encrypt(&k4_challenge, &k4_challenge, k4_sched, 1);
  3997. #endif /* NT */
  3998. ckhexdump("auth_is des_ecb_encrypt(k4_challenge_key,k4_challenge,1)",
  3999. k4_challenge,8);
  4000. #endif /* MIT_CURRENT */
  4001. SendK4AuthSB(KRB4_RESPONSE,(void *)k4_challenge,sizeof(k4_challenge));
  4002. #endif /* ENCRYPTION */
  4003. mutual_complete = 1;
  4004. break;
  4005. default:
  4006. if (1)
  4007. printf("Unknown Kerberos option %d\r\n", data[-1]);
  4008. SendK4AuthSB(KRB_REJECT, 0, 0);
  4009. return(AUTH_FAILURE);
  4010. }
  4011. krb4_errno = r;
  4012. makestr(&krb4_errmsg,krb_get_err_text_entry(krb4_errno));
  4013. return(AUTH_SUCCESS);
  4014. }
  4015. #endif /* KRB4 */
  4016. #ifdef KRB5
  4017. int
  4018. ck_krb5_autoget_TGT(char * realm)
  4019. {
  4020. extern struct krb_op_data krb_op;
  4021. extern struct krb5_init_data krb5_init;
  4022. char passwd[PWD_SZ];
  4023. char prompt[64];
  4024. char * saverealm=NULL;
  4025. int rc = -1;
  4026. extern char * k5prprompt;
  4027. extern char * k5pwprompt;
  4028. ini_kerb(); /* Place defaults in above structs */
  4029. passwd[0] = '\0';
  4030. if ( krb5_init.principal == NULL ||
  4031. krb5_init.principal[0] == '\0') {
  4032. int ok = uq_txt(NULL,k5prprompt && k5prprompt[0] ? k5prprompt :
  4033. "Kerberos 5 Principal: ",2,NULL,passwd,PWD_SZ-1,NULL,
  4034. DEFAULT_UQ_TIMEOUT);
  4035. if ( ok && passwd[0] )
  4036. makestr(&krb5_init.principal,passwd);
  4037. else
  4038. return(0);
  4039. }
  4040. /* Save realm in init structure so it can be restored */
  4041. if ( realm ) {
  4042. saverealm = krb5_init.realm;
  4043. krb5_init.realm = realm;
  4044. }
  4045. if ( passwd[0] || !(pwbuf[0] && pwflg) ) {
  4046. int ok;
  4047. if ( k5pwprompt && k5pwprompt[0] &&
  4048. (strlen(k5pwprompt) + strlen(krb5_init.principal) +
  4049. strlen(krb5_init.realm) - 4) < sizeof(prompt)) {
  4050. sprintf(prompt,k5pwprompt,krb5_init.principal,krb5_init.realm);
  4051. } else
  4052. ckmakxmsg(prompt,sizeof(prompt),
  4053. k5pwprompt && k5pwprompt[0] ? k5pwprompt :
  4054. "Kerberos 5 Password for ",
  4055. krb5_init.principal,"@",krb5_init.realm,": ",
  4056. NULL,NULL,NULL,NULL,NULL,NULL,NULL
  4057. );
  4058. ok = uq_txt(NULL,prompt,2,NULL,passwd,PWD_SZ-1,NULL,
  4059. DEFAULT_UQ_TIMEOUT);
  4060. if ( !ok )
  4061. passwd[0] = '\0';
  4062. } else {
  4063. ckstrncpy(passwd,(char *)pwbuf,sizeof(passwd));
  4064. #ifdef OS2
  4065. if ( pwcrypt )
  4066. ck_encrypt((char *)passwd);
  4067. #endif /* OS2 */
  4068. }
  4069. if ( passwd[0] ) {
  4070. extern struct krb4_init_data krb4_init;
  4071. char * savek4realm=NULL;
  4072. makestr(&krb5_init.password,passwd);
  4073. if ( krb5_d_getk4 ) {
  4074. krb5_init.getk4 = 1;
  4075. makestr(&krb4_init.principal,krb5_init.principal);
  4076. makestr(&krb4_init.password,passwd);
  4077. if ( realm ) {
  4078. savek4realm = krb4_init.realm;
  4079. krb4_init.realm = realm;
  4080. }
  4081. rc = ck_krb5_initTGT(&krb_op, &krb5_init,&krb4_init);
  4082. if ( savek4realm )
  4083. krb4_init.realm = savek4realm;
  4084. free(krb4_init.password);
  4085. krb4_init.password = NULL;
  4086. } else {
  4087. rc = ck_krb5_initTGT(&krb_op, &krb5_init,NULL);
  4088. }
  4089. free(krb5_init.password);
  4090. krb5_init.password = NULL;
  4091. memset(passwd,0,PWD_SZ);
  4092. }
  4093. /* restore realm to init structure if needed */
  4094. if ( saverealm )
  4095. krb5_init.realm = saverealm;
  4096. return(rc == 0);
  4097. }
  4098. static krb5_error_code
  4099. #ifdef CK_ANSIC
  4100. k5_get_ccache( krb5_context k5_context, krb5_ccache * p_ccache,
  4101. char * cc_name )
  4102. #else /* CK_ANSIC */
  4103. k5_get_ccache(k5_context, p_ccache, cc_name)
  4104. krb5_context k5_context;
  4105. krb5_ccache * p_ccache;
  4106. char * cc_name;
  4107. #endif /* CK_ANSIC */
  4108. {
  4109. krb5_error_code r=0;
  4110. char cc_tmp[CKMAXPATH+1];
  4111. const char * def_name = NULL;
  4112. #ifndef HEIMDAL
  4113. if ( cc_name ) {
  4114. if ( strncmp("FILE:",cc_name,5) &&
  4115. strncmp("MEMORY:",cc_name,7) &&
  4116. strncmp("API:",cc_name,4) &&
  4117. strncmp("STDIO:",cc_name,6) &&
  4118. strncmp("MSLSA:",cc_name,6))
  4119. #ifdef NT
  4120. ckmakmsg(cc_tmp,CKMAXPATH,"API:",cc_name,NULL,NULL);
  4121. #else /* NT */
  4122. ckmakmsg(cc_tmp,CKMAXPATH,"FILE:",cc_name,NULL,NULL);
  4123. #endif /* NT */
  4124. else {
  4125. ckstrncpy(cc_tmp,cc_name,CKMAXPATH);
  4126. }
  4127. r = krb5_cc_resolve (k5_context, cc_tmp, p_ccache);
  4128. if (r != 0) {
  4129. com_err("k5_get_ccache resolving ccache",r,
  4130. cc_tmp);
  4131. } else {
  4132. /* Make sure GSSAPI sees the same cache we are using */
  4133. char buf[128];
  4134. ckmakmsg((char *)buf,128,"KRB5CCNAME=",cc_tmp,NULL,NULL);
  4135. putenv(buf);
  4136. }
  4137. } else if ( krb5_d_cc ) {
  4138. if ( strncmp("FILE:",krb5_d_cc,5) &&
  4139. strncmp("MEMORY:",krb5_d_cc,7) &&
  4140. strncmp("API:",krb5_d_cc,4) &&
  4141. strncmp("STDIO:",krb5_d_cc,6) &&
  4142. strncmp("MSLSA:", krb5_d_cc,6))
  4143. #ifdef NT
  4144. ckmakmsg(cc_tmp,CKMAXPATH,"API:",krb5_d_cc,NULL,NULL);
  4145. #else /* NT */
  4146. ckmakmsg(cc_tmp,CKMAXPATH,"FILE:",krb5_d_cc,NULL,NULL);
  4147. #endif /* NT */
  4148. else {
  4149. ckstrncpy(cc_tmp,krb5_d_cc,CKMAXPATH);
  4150. }
  4151. r = krb5_cc_resolve (k5_context, cc_tmp, p_ccache);
  4152. if (r != 0) {
  4153. com_err("k5_get_ccache resolving ccache",r,
  4154. krb5_d_cc);
  4155. } else {
  4156. /* Make sure GSSAPI sees the same cache we are using */
  4157. char buf[128];
  4158. ckmakmsg((char *)buf,128,"KRB5CCNAME=",cc_tmp,NULL,NULL);
  4159. putenv(buf);
  4160. }
  4161. } else
  4162. #endif /* HEIMDAL */
  4163. {
  4164. if ((r = krb5_cc_default(k5_context, p_ccache))) {
  4165. com_err("k5_get_ccache",r,"while getting default ccache");
  4166. }
  4167. }
  4168. /* do not set krb5_errno/krb5_errmsg here since the value returned */
  4169. /* is being passed internally within the krb5 functions. */
  4170. return(r);
  4171. }
  4172. char *
  4173. ck_krb5_realmofhost(char *host)
  4174. {
  4175. char ** realmlist=NULL;
  4176. krb5_context private_context=NULL;
  4177. static char * realm = NULL;
  4178. if ( !host )
  4179. return NULL;
  4180. if ( realm ) {
  4181. free(realm);
  4182. realm = NULL;
  4183. }
  4184. /* create private_context */
  4185. if (krb5_init_context(&private_context)) {
  4186. debug(F110,"ck_krb5_realmofhost()","unable to init_context",0);
  4187. return(NULL);
  4188. }
  4189. krb5_get_host_realm(private_context,host,&realmlist);
  4190. if (realmlist && realmlist[0]) {
  4191. makestr(&realm,realmlist[0]);
  4192. krb5_free_host_realm(private_context,realmlist);
  4193. realmlist = NULL;
  4194. }
  4195. if ( private_context ) {
  4196. krb5_free_context(private_context);
  4197. private_context = NULL;
  4198. }
  4199. if (ckstrchr(realm,'.') == NULL) {
  4200. int n = 0;
  4201. char * p = host;
  4202. while ( (p = ckstrchr(p,'.')) != NULL ) {
  4203. n++;
  4204. p++;
  4205. }
  4206. if (n == 1) {
  4207. makestr(&realm,host);
  4208. ckupper(realm);
  4209. } else {
  4210. free(realm);
  4211. realm = NULL;
  4212. }
  4213. }
  4214. return(realm);
  4215. }
  4216. /*
  4217. *
  4218. * K5_auth_send - gets authentication bits we need to send to KDC.
  4219. *
  4220. * Code lifted from telnet sample code in the appl directory.
  4221. *
  4222. * Result is left in k5_auth
  4223. *
  4224. * Returns: 0 on failure, 1 on success
  4225. *
  4226. */
  4227. static int
  4228. #ifdef CK_ANSIC
  4229. k5_auth_send(int how, int encrypt, int forward)
  4230. #else
  4231. k5_auth_send(how,encrypt,forward) int how; int encrypt; int forward;
  4232. #endif
  4233. {
  4234. krb5_error_code r=0;
  4235. krb5_ccache ccache=NULL;
  4236. #ifndef HEIMDAL
  4237. krb5_creds creds;
  4238. #endif /* HEIMDAL */
  4239. krb5_creds * new_creds=NULL;
  4240. #ifdef CK_ENCRYPTION
  4241. krb5_keyblock *newkey = 0;
  4242. #endif /* CK_ENCRYPTION */
  4243. krb5_flags ap_opts, auth_flags;
  4244. char type_check[32];
  4245. krb5_data checksum;
  4246. int len=0;
  4247. char * realm = NULL;
  4248. char tgt[256];
  4249. realm = ck_krb5_realmofhost(szHostName);
  4250. if (!realm) {
  4251. ckstrncpy(strTmp, "Can't find realm for host \"",AUTHTMPBL);
  4252. ckstrncat(strTmp, szHostName,AUTHTMPBL);
  4253. ckstrncat(strTmp, "\"",AUTHTMPBL);
  4254. printf("?Kerberos 5 error: %s\r\n",strTmp);
  4255. krb5_errno = KRB5_ERR_HOST_REALM_UNKNOWN;
  4256. makestr(&krb5_errmsg,strTmp);
  4257. return(0);
  4258. }
  4259. ckmakmsg(tgt,sizeof(tgt),"krbtgt/",realm,"@",realm);
  4260. debug(F110,"k5_auth_send TGT",tgt,0);
  4261. if ( krb5_autoget &&
  4262. !((ck_krb5_tkt_isvalid(NULL,tgt) > 0) ||
  4263. (ck_krb5_is_tgt_valid() > 0)) )
  4264. ck_krb5_autoget_TGT(realm);
  4265. r = k5_get_ccache(k5_context,&ccache,NULL);
  4266. if ( r ) {
  4267. com_err(NULL, r, "while authorizing (0).");
  4268. krb5_errno = r;
  4269. makestr(&krb5_errmsg,error_message(krb5_errno));
  4270. return(0);
  4271. }
  4272. #ifndef HEIMDAL
  4273. memset((char *)&creds, 0, sizeof(creds));
  4274. if (r = krb5_sname_to_principal(k5_context, szHostName,
  4275. krb5_d_srv ? krb5_d_srv : KRB5_SERVICE_NAME,
  4276. KRB5_NT_SRV_HST, &creds.server)) {
  4277. com_err(NULL, r, "while authorizing (1).");
  4278. krb5_errno = r;
  4279. makestr(&krb5_errmsg,error_message(krb5_errno));
  4280. return(0);
  4281. }
  4282. if (forward_flag) {
  4283. if (fwd_server) {
  4284. krb5_free_principal(k5_context,fwd_server);
  4285. fwd_server = NULL;
  4286. }
  4287. krb5_copy_principal(k5_context,creds.server,&fwd_server);
  4288. }
  4289. r = krb5_cc_get_principal(k5_context, ccache, &creds.client);
  4290. if (r) {
  4291. com_err(NULL, r, "while authorizing (2).");
  4292. krb5_free_cred_contents(k5_context, &creds);
  4293. krb5_errno = r;
  4294. makestr(&krb5_errmsg,error_message(krb5_errno));
  4295. return(0);
  4296. }
  4297. if (szUserName[0] == '\0') { /* Get user name now */
  4298. len = krb5_princ_component(k5_context, creds.client, 0)->length;
  4299. if ( len < sizeof(szUserName) ) {
  4300. memcpy(szUserName,
  4301. krb5_princ_component(k5_context, creds.client, 0)->data,
  4302. len); /* safe */
  4303. } else
  4304. len = 0;
  4305. szUserName[len] = '\0';
  4306. } else {
  4307. char * name = NULL;
  4308. len = krb5_princ_component(k5_context, creds.client, 0)->length;
  4309. if ( len == strlen(szUserName) ) {
  4310. name = krb5_princ_component(k5_context, creds.client, 0)->data;
  4311. #ifdef OS2
  4312. if ( !strnicmp(szUserName,name,len) )
  4313. memcpy(szUserName,name,len); /* safe */
  4314. #endif /* OS2 */
  4315. }
  4316. }
  4317. if ( tn_auth_krb5_des_bug ) { /* !ALLOW_KRB_3DES_ENCRYPT */
  4318. /* Not sure if this is necessary anymore. What impact does it have
  4319. * on Win2000 TGTs that use DES_CBC_MD5 or RC4_HMAC?
  4320. *
  4321. * This prevents using 3DES Service Tickets.
  4322. */
  4323. creds.keyblock.enctype=ENCTYPE_DES_CBC_CRC;
  4324. }
  4325. if (r = krb5_get_credentials(k5_context, 0,
  4326. ccache, &creds, &new_creds)) {
  4327. com_err(NULL, r, "while authorizing (3).");
  4328. krb5_free_cred_contents(k5_context, &creds);
  4329. krb5_errno = r;
  4330. makestr(&krb5_errmsg,error_message(krb5_errno));
  4331. return(0);
  4332. }
  4333. #endif /* HEIMDAL */
  4334. if (auth_context) {
  4335. krb5_auth_con_free(k5_context, auth_context);
  4336. auth_context = 0;
  4337. }
  4338. if (r = krb5_auth_con_init(k5_context, &auth_context)) {
  4339. com_err(NULL, r, "while initializing auth context");
  4340. krb5_errno = r;
  4341. makestr(&krb5_errmsg,error_message(krb5_errno));
  4342. return(0);
  4343. }
  4344. /* UPDATE for START_TLS. AUTH_ENCRYPT_START_TLS and inclusion of */
  4345. /* client and then server finished messages. */
  4346. type_check[0] = AUTHTYPE_KERBEROS_V5;
  4347. type_check[1] = AUTH_CLIENT_TO_SERVER |
  4348. (how ? AUTH_HOW_MUTUAL : AUTH_HOW_ONE_WAY) |
  4349. (encrypt) |
  4350. (forward ? INI_CRED_FWD_ON : INI_CRED_FWD_OFF);
  4351. #ifdef CK_SSL
  4352. if (encrypt == AUTH_ENCRYPT_START_TLS) {
  4353. ssl_get_client_finished(&type_check[2],12);
  4354. ssl_get_server_finished(&type_check[14],12);
  4355. }
  4356. #endif /* CK_SSL */
  4357. #ifndef HEIMDAL
  4358. checksum.magic = KV5M_DATA;
  4359. #endif /* HEIMDAL */
  4360. checksum.length =
  4361. #ifdef CK_SSL
  4362. (encrypt == AUTH_ENCRYPT_START_TLS) ? 26 :
  4363. #endif /* CK_SSL */
  4364. 2;
  4365. checksum.data = (char *)&type_check;
  4366. ap_opts = 0;
  4367. if ((how & AUTH_HOW_MASK) == AUTH_HOW_MUTUAL)
  4368. ap_opts |= AP_OPTS_MUTUAL_REQUIRED;
  4369. #ifdef HEIMDAL
  4370. r = krb5_auth_setkeytype(k5_context, auth_context, KEYTYPE_DES);
  4371. if (r)
  4372. com_err(NULL, r, "while setting auth keytype");
  4373. r = krb5_auth_con_setaddrs_from_fd(k5_context,auth_context, &ttyfd);
  4374. if (r)
  4375. com_err(NULL, r, "while setting auth addrs");
  4376. r = krb5_mk_req(k5_context, &auth_context, ap_opts,
  4377. krb5_d_srv ? krb5_d_srv : KRB5_SERVICE_NAME,
  4378. szHostName, &checksum, ccache, &k5_auth);
  4379. if (r)
  4380. com_err(NULL, r, "while making request");
  4381. #else /* HEIMDAL */
  4382. auth_flags = KRB5_AUTH_CONTEXT_RET_TIME;
  4383. #ifdef CK_ENCRYPTION
  4384. ap_opts |= AP_OPTS_USE_SUBKEY;
  4385. #endif /* CK_ENCRYPTION */
  4386. #ifdef TLS_VERIFY
  4387. if ((how & AUTH_ENCRYPT_MASK) == AUTH_ENCRYPT_START_TLS) {
  4388. auth_flags |= KRB5_AUTH_CONTEXT_DO_SEQUENCE;
  4389. if (!krb5_d_no_addresses)
  4390. r = krb5_auth_con_genaddrs(k5_context, auth_context, ttyfd,
  4391. KRB5_AUTH_CONTEXT_GENERATE_REMOTE_FULL_ADDR);
  4392. }
  4393. #endif /* CK_SSL */
  4394. krb5_auth_con_setflags(k5_context, auth_context, auth_flags);
  4395. r = krb5_mk_req_extended(k5_context, &auth_context, ap_opts,
  4396. &checksum, new_creds, &k5_auth);
  4397. #endif /* HEIMDAL */
  4398. #ifdef CK_ENCRYPTION
  4399. if (!r) {
  4400. r = krb5_auth_con_getlocalsubkey(k5_context, auth_context, &newkey);
  4401. if (r)
  4402. r = krb5_auth_con_getkey(k5_context, auth_context, &newkey);
  4403. if (k5_session_key) {
  4404. krb5_free_keyblock(k5_context, k5_session_key);
  4405. k5_session_key = 0;
  4406. }
  4407. }
  4408. if (newkey) {
  4409. /*
  4410. * keep the key in our private storage, but don't use it
  4411. * yet---see kerberos5_reply() below
  4412. */
  4413. #ifdef HEIMDAL
  4414. if ((newkey->keytype == ETYPE_DES_CBC_CRC) ||
  4415. (newkey->keytype == ETYPE_DES_CBC_MD5) ||
  4416. (newkey->keytype == ETYPE_DES_CBC_MD4))
  4417. {
  4418. debug(F111,"k5_auth_send()","newkey->keytype",newkey->keytype);
  4419. krb5_copy_keyblock(k5_context, newkey, &k5_session_key);
  4420. }
  4421. #else /* HEIMDAL */
  4422. /* look for all possible DES keys first - just for compatibility */
  4423. /* other key types are much less likely to be available */
  4424. if ((newkey->enctype == ENCTYPE_DES_CBC_CRC) ||
  4425. (newkey->enctype == ENCTYPE_DES_CBC_MD5) ||
  4426. (newkey->enctype == ENCTYPE_DES_CBC_MD4))
  4427. {
  4428. debug(F111,"k5_auth_send()","newkey->enctype",newkey->enctype);
  4429. krb5_copy_keyblock(k5_context, newkey, &k5_session_key);
  4430. }
  4431. else if ((new_creds->keyblock.enctype == ENCTYPE_DES_CBC_CRC) ||
  4432. (new_creds->keyblock.enctype == ENCTYPE_DES_CBC_MD5))
  4433. {
  4434. /* use the session key in credentials instead */
  4435. debug(F111,"k5_auth_send()","new_creds->keyblock.enctype",
  4436. new_creds->keyblock.enctype);
  4437. krb5_copy_keyblock(k5_context,
  4438. &new_creds->keyblock, &k5_session_key);
  4439. }
  4440. else if (newkey->enctype != 0)
  4441. {
  4442. debug(F111,"k5_auth_send()","newkey->enctype",newkey->enctype);
  4443. krb5_copy_keyblock(k5_context, newkey, &k5_session_key);
  4444. }
  4445. else if (new_creds->keyblock.enctype != 0)
  4446. {
  4447. /* use the session key in credentials instead */
  4448. debug(F111,"k5_auth_send()","new_creds->keyblock.enctype",
  4449. new_creds->keyblock.enctype);
  4450. krb5_copy_keyblock(k5_context,
  4451. &new_creds->keyblock, &k5_session_key);
  4452. }
  4453. else {
  4454. debug(F110,"k5_auth_send()","NO KEY in newkey",0);
  4455. }
  4456. #endif /* HEIMDAL */
  4457. krb5_free_keyblock(k5_context, newkey);
  4458. }
  4459. #endif /* CK_ENCRYPTION */
  4460. #ifndef HEIMDAL
  4461. krb5_free_cred_contents(k5_context, &creds);
  4462. krb5_free_creds(k5_context, new_creds);
  4463. #endif /* HEIMDAL */
  4464. krb5_cc_close(k5_context,ccache);
  4465. if (r) {
  4466. com_err(NULL, r, "while authorizing (4).");
  4467. krb5_errno = r;
  4468. makestr(&krb5_errmsg,error_message(krb5_errno));
  4469. return(0);
  4470. }
  4471. krb5_errno = 0;
  4472. makestr(&krb5_errmsg,"OK");
  4473. return(1);
  4474. }
  4475. /*
  4476. * K5_auth_reply -- checks the reply for mutual authentication.
  4477. */
  4478. static int
  4479. #ifdef CK_ANSIC
  4480. k5_auth_reply(int how, unsigned char *data, int cnt)
  4481. #else
  4482. k5_auth_reply(how,data,cnt) int how; unsigned char *data; int cnt;
  4483. #endif
  4484. {
  4485. #ifdef CK_ENCRYPTION
  4486. Session_Key skey;
  4487. #endif /* CK_ENCRYPTION */
  4488. data += 4; /* Point to status byte */
  4489. cnt -=5;
  4490. switch (*data++) {
  4491. case KRB_REJECT:
  4492. if (cnt > 0) {
  4493. char *s;
  4494. int len;
  4495. ckstrncpy(strTmp,"Kerberos V5 refuses authentication because\r\n",
  4496. sizeof(strTmp));
  4497. len = strlen(strTmp);
  4498. if ( len + cnt < sizeof(strTmp) ) {
  4499. s = strTmp + strlen(strTmp);
  4500. memcpy(s, data, cnt); /* safe */
  4501. s[cnt] = 0;
  4502. }
  4503. } else
  4504. ckstrncpy(strTmp,"Kerberos V5 refuses authentication",
  4505. sizeof(strTmp));
  4506. krb5_errno = -1;
  4507. makestr(&krb5_errmsg,strTmp);
  4508. printf("Kerberos authentication failed!\r\n%s\r\n",strTmp);
  4509. auth_finished(AUTH_REJECT);
  4510. return AUTH_FAILURE;
  4511. case KRB_ACCEPT:
  4512. if (!mutual_complete) {
  4513. if ((how & AUTH_HOW_MASK) == AUTH_HOW_MUTUAL && !mutual_complete) {
  4514. ckstrncpy(strTmp,
  4515. "Kerberos V5 accepted you, but didn't provide"
  4516. " mutual authentication",sizeof(strTmp));
  4517. printf("Kerberos authentication failed!\r\n%s\r\n",strTmp);
  4518. krb5_errno = -1;
  4519. makestr(&krb5_errmsg,strTmp);
  4520. auth_finished(AUTH_REJECT);
  4521. return AUTH_FAILURE;
  4522. }
  4523. #ifdef CK_ENCRYPTION
  4524. if (k5_session_key) {
  4525. if ( tn_auth_krb5_des_bug ) { /* !ALLOW_KRB_3DES_ENCRYPT */
  4526. skey.type = SK_DES;
  4527. skey.length = 8;
  4528. #ifdef HEIMDAL
  4529. skey.data = k5_session_key->keyvalue.data;
  4530. #else /* HEIMDAL */
  4531. skey.data = k5_session_key->contents;
  4532. #endif /* HEIMDAL */
  4533. } else {
  4534. #ifdef HEIMDAL
  4535. switch ( k5_session_key->keytype ) {
  4536. case ETYPE_DES_CBC_CRC:
  4537. case ETYPE_DES_CBC_MD5:
  4538. case ETYPE_DES_CBC_MD4:
  4539. skey.type = SK_DES;
  4540. skey.length = 8;
  4541. break;
  4542. default:
  4543. skey.type = SK_GENERIC;
  4544. skey.length = k5_session_key->length;
  4545. encrypt_dont_support(ENCTYPE_DES_CFB64);
  4546. encrypt_dont_support(ENCTYPE_DES_OFB64);
  4547. }
  4548. skey.data = k5_session_key->keyvalue.data;
  4549. #else /* HEIMDAL */
  4550. switch ( k5_session_key->enctype ) {
  4551. case ENCTYPE_DES_CBC_CRC:
  4552. case ENCTYPE_DES_CBC_MD5:
  4553. case ENCTYPE_DES_CBC_MD4:
  4554. skey.type = SK_DES;
  4555. skey.length = 8;
  4556. default:
  4557. skey.type = SK_GENERIC;
  4558. skey.length = k5_session_key->length;
  4559. encrypt_dont_support(ENCTYPE_DES_CFB64);
  4560. encrypt_dont_support(ENCTYPE_DES_OFB64);
  4561. }
  4562. skey.data = k5_session_key->contents;
  4563. #endif /* HEIMDAL */
  4564. }
  4565. encrypt_session_key(&skey, AUTH_CLIENT_TO_SERVER);
  4566. }
  4567. #endif /* CK_ENCRYPTION */
  4568. }
  4569. if ( cnt > 0 ) {
  4570. char *s;
  4571. int len;
  4572. ckstrncpy(strTmp,"Kerberos V5 accepts you as ",sizeof(strTmp));
  4573. len = strlen(strTmp);
  4574. if ( len + cnt < sizeof(strTmp) ) {
  4575. s = strTmp + strlen(strTmp);
  4576. memcpy(s,data,cnt);
  4577. s[cnt] = 0;
  4578. }
  4579. }
  4580. accept_complete = 1;
  4581. printf("%s\r\n",strTmp);
  4582. #ifdef FORWARD
  4583. if (forward_flag
  4584. #ifdef COMMENT
  4585. /* Marc Horowitz <marc@mit.edu> has successfully argued
  4586. that it is indeed safe to send Forwarded credentials
  4587. to an untrusted host.
  4588. */
  4589. && (auth_how & AUTH_HOW_MASK) == AUTH_HOW_MUTUAL
  4590. #endif /* COMMENT */
  4591. )
  4592. kerberos5_forward();
  4593. #endif /* FORWARD */
  4594. krb5_errno = 0;
  4595. makestr(&krb5_errmsg,strTmp);
  4596. auth_finished(AUTH_USER);
  4597. return AUTH_SUCCESS;
  4598. case KRB5_RESPONSE:
  4599. #ifdef TLS_VERIFY
  4600. if ((how & AUTH_ENCRYPT_MASK) == AUTH_ENCRYPT_START_TLS &&
  4601. !krb5_tls_verified) {
  4602. printf(
  4603. "Man in the middle attack detected. Session terminated.\r\n");
  4604. #ifndef BETATEST
  4605. netclos();
  4606. #endif /* BETATEST */
  4607. krb5_errno = -1;
  4608. makestr(&krb5_errmsg,"TLS not verified");
  4609. auth_finished(AUTH_REJECT);
  4610. return AUTH_FAILURE;
  4611. }
  4612. if((ssl_active_flag || tls_active_flag) &&
  4613. (how & AUTH_ENCRYPT_MASK) == AUTH_ENCRYPT_START_TLS) {
  4614. printf("TLS session parameters verified by Kerberos 5\r\n");
  4615. }
  4616. #endif /* TLS_VERIFY */
  4617. if ((how & AUTH_HOW_MASK) == AUTH_HOW_MUTUAL) {
  4618. /* the rest of the reply should contain a krb_ap_rep */
  4619. krb5_ap_rep_enc_part *reply;
  4620. krb5_data inbuf;
  4621. krb5_error_code r;
  4622. inbuf.length = cnt;
  4623. inbuf.data = (char *)data;
  4624. if (r = krb5_rd_rep(k5_context, auth_context, &inbuf, &reply)) {
  4625. com_err(NULL, r, "while authorizing. (5)");
  4626. krb5_errno = r;
  4627. makestr(&krb5_errmsg,error_message(krb5_errno));
  4628. auth_finished(AUTH_REJECT);
  4629. return AUTH_FAILURE;
  4630. }
  4631. krb5_free_ap_rep_enc_part(k5_context, reply);
  4632. #ifdef CK_ENCRYPTION
  4633. if (encrypt_flag && k5_session_key) {
  4634. if ( tn_auth_krb5_des_bug ) { /* !ALLOW_KRB_3DES_ENCRYPT */
  4635. skey.type = SK_DES;
  4636. skey.length = 8;
  4637. #ifdef HEIMDAL
  4638. skey.data = k5_session_key->keyvalue.data;
  4639. #else /* HEIMDAL */
  4640. skey.data = k5_session_key->contents;
  4641. #endif /* HEIMDAL */
  4642. } else {
  4643. #ifdef HEIMDAL
  4644. switch ( k5_session_key->keytype ) {
  4645. case ETYPE_DES_CBC_CRC:
  4646. case ETYPE_DES_CBC_MD5:
  4647. case ETYPE_DES_CBC_MD4:
  4648. skey.type = SK_DES;
  4649. skey.length = 8;
  4650. default:
  4651. skey.type = SK_GENERIC;
  4652. skey.length = k5_session_key->length;
  4653. }
  4654. skey.data = k5_session_key->keyvalue.data;
  4655. #else /* HEIMDAL */
  4656. switch ( k5_session_key->enctype ) {
  4657. case ENCTYPE_DES_CBC_CRC:
  4658. case ENCTYPE_DES_CBC_MD5:
  4659. case ENCTYPE_DES_CBC_MD4:
  4660. skey.type = SK_DES;
  4661. skey.length = 8;
  4662. break;
  4663. default:
  4664. skey.type = SK_GENERIC;
  4665. skey.length = k5_session_key->length;
  4666. }
  4667. skey.data = k5_session_key->contents;
  4668. #endif /* HEIMDAL */
  4669. }
  4670. encrypt_session_key(&skey, AUTH_CLIENT_TO_SERVER);
  4671. }
  4672. #endif /* ENCRYPTION */
  4673. mutual_complete = 1;
  4674. }
  4675. ckstrncpy(strTmp,"Remote machine has been mutually authenticated",
  4676. sizeof(strTmp));
  4677. krb5_errno = 0;
  4678. makestr(&krb5_errmsg,strTmp);
  4679. printf("%s\r\n",strTmp);
  4680. auth_finished(AUTH_USER);
  4681. return AUTH_SUCCESS;
  4682. #ifdef FORWARD
  4683. case KRB5_FORWARD_ACCEPT:
  4684. forwarded_tickets = 1;
  4685. ckstrncpy(strTmp,"Remote machine has accepted forwarded credentials",
  4686. sizeof(strTmp));
  4687. krb5_errno = 0;
  4688. makestr(&krb5_errmsg,strTmp);
  4689. printf("%s\r\n",strTmp);
  4690. return AUTH_SUCCESS;
  4691. case KRB5_FORWARD_REJECT:
  4692. forwarded_tickets = 0;
  4693. if (cnt > 0) {
  4694. char *s;
  4695. int len;
  4696. len = ckstrncpy(strTmp,
  4697. "Kerberos V5 refuses forwarded credentials because ",
  4698. sizeof(strTmp));
  4699. if ( len + cnt < sizeof(strTmp) ) {
  4700. s = strTmp + strlen(strTmp);
  4701. memcpy(s, data, cnt);
  4702. s[cnt] = 0;
  4703. }
  4704. } else
  4705. ckstrncpy(strTmp, "Kerberos V5 refuses forwarded credentials",
  4706. sizeof(strTmp));
  4707. printf("%s\r\n",strTmp);
  4708. krb5_errno = -1;
  4709. makestr(&krb5_errmsg,strTmp);
  4710. return AUTH_SUCCESS;
  4711. #endif /* FORWARD */
  4712. #ifdef TLS_VERIFY
  4713. case KRB5_TLS_VERIFY:
  4714. if ((how & AUTH_ENCRYPT_MASK) == AUTH_ENCRYPT_START_TLS) {
  4715. krb5_data reply, msg;
  4716. char tls_verify[24];
  4717. krb5_replay_data repdata;
  4718. krb5_error_code r;
  4719. ssl_get_server_finished(&tls_verify[0],12);
  4720. ssl_get_client_finished(&tls_verify[12],12);
  4721. reply.data = (char *)data;
  4722. reply.length = cnt;
  4723. krb5_auth_con_genaddrs(k5_context, auth_context, ttyfd,
  4724. KRB5_AUTH_CONTEXT_GENERATE_REMOTE_FULL_ADDR);
  4725. if (r = krb5_rd_safe(k5_context,auth_context,&reply,&msg,&repdata))
  4726. {
  4727. com_err("", r, "decoding tls verifier");
  4728. krb5_errno = r;
  4729. makestr(&krb5_errmsg,"TLS verify failure");
  4730. auth_finished(AUTH_REJECT);
  4731. return(AUTH_FAILURE);
  4732. }
  4733. if ( msg.length == 24 && !memcmp(msg.data,tls_verify,24) )
  4734. krb5_tls_verified = 1;
  4735. krb5_free_data_contents(k5_context,&msg);
  4736. if (krb5_tls_verified)
  4737. return(AUTH_SUCCESS);
  4738. }
  4739. printf("Man in the middle attack detected. Session terminated.\r\n");
  4740. netclos();
  4741. krb5_errno = -1;
  4742. makestr(&krb5_errmsg,"TLS verify failure");
  4743. auth_finished(AUTH_REJECT);
  4744. return(AUTH_FAILURE);
  4745. #endif /* CK_SSL */
  4746. default:
  4747. krb5_errno = -1;
  4748. makestr(&krb5_errmsg,"Unknown reply type");
  4749. auth_finished(AUTH_REJECT);
  4750. return AUTH_FAILURE; /* Unknown reply type */
  4751. }
  4752. }
  4753. #ifdef FORWARD
  4754. /* Decode, decrypt and store the forwarded creds in the local ccache. */
  4755. /* Needed for KRB5_FORWARD */
  4756. static krb5_error_code
  4757. rd_and_store_for_creds(context, auth_context, inbuf, client)
  4758. krb5_context context;
  4759. krb5_auth_context auth_context;
  4760. krb5_data *inbuf;
  4761. krb5_const_principal client;
  4762. {
  4763. krb5_creds ** creds=NULL;
  4764. krb5_error_code retval;
  4765. krb5_ccache ccache=NULL;
  4766. #ifdef HEIMDAL
  4767. /*
  4768. Heimdal Telnetd creates the cache file at this point and sets
  4769. the KRB5CCNAME environment variable.
  4770. struct passwd *pwd;
  4771. char ccname[1024];
  4772. pwd = getpwnam(szUserNameRequested);
  4773. if (pwd == NULL)
  4774. break;
  4775. snprintf(ccname, sizeof(ccname)-1, "FILE:/tmp/krb5cc_%u",pwd->pw_uid);
  4776. retval = krb5_cc_resolve(context,ccname,&ccache);
  4777. chown(ccname + 5, pwd->pw_uid, -1);
  4778. */
  4779. #endif /* HEIMDAL */
  4780. if (retval = k5_get_ccache(context,&ccache,NULL))
  4781. return(retval);
  4782. #ifdef HEIMDAL
  4783. if ((retval = krb5_cc_initialize(context, ccache, client)))
  4784. return(retval);
  4785. if ((retval = krb5_rd_cred(context, auth_context, ccache, inbuf)))
  4786. return(retval);
  4787. #else /* HEIMDAL */
  4788. if ((retval = krb5_rd_cred(context, auth_context, inbuf, &creds, NULL)))
  4789. return(retval);
  4790. if ((retval = krb5_cc_initialize(context, ccache, creds[0]->client)))
  4791. goto cleanup;
  4792. if ((retval = krb5_cc_store_cred(context, ccache, creds[0])))
  4793. goto cleanup;
  4794. if ((retval = krb5_cc_close(context, ccache)))
  4795. goto cleanup;
  4796. cleanup:
  4797. krb5_free_tgt_creds(context, creds);
  4798. #endif /* HEIMDAL */
  4799. return retval;
  4800. }
  4801. #endif /* FORWARD */
  4802. /*
  4803. *
  4804. * K5_auth_is.
  4805. *
  4806. */
  4807. static int
  4808. #ifdef CK_ANSIC
  4809. k5_auth_is(int how, unsigned char *data, int cnt)
  4810. #else
  4811. k5_auth_is(how,data,cnt) int how; unsigned char *data; int cnt;
  4812. #endif
  4813. {
  4814. int r = 0;
  4815. krb5_principal server;
  4816. krb5_keyblock *newkey = NULL;
  4817. krb5_data outbuf;
  4818. char errbuf[128]="";
  4819. char *getenv();
  4820. #ifndef HEIMDAL
  4821. krb5_authenticator *authenticator;
  4822. krb5_keytab keytabid = 0;
  4823. #endif /* HEIMDAL */
  4824. krb5_data inbuf;
  4825. #ifdef CK_ENCRYPTION
  4826. Session_Key skey;
  4827. #endif /* CK_ENCRYPTION */
  4828. char princ[256]="";
  4829. int len;
  4830. data += 4; /* Point to status byte */
  4831. cnt -= 4;
  4832. ckhexdump("k5_auth_is data",data,cnt);
  4833. debug(F111,"k5_auth_is","how",how);
  4834. if (cnt-- < 1) {
  4835. auth_finished(AUTH_REJECT);
  4836. return AUTH_FAILURE;
  4837. }
  4838. switch (*data++) {
  4839. case KRB_AUTH:
  4840. k5_auth.data = (char *)data;
  4841. k5_auth.length = cnt;
  4842. debug(F110,"k5_auth_is","KRB_AUTH",0);
  4843. debug(F111,"k5_auth_is","auth_context",auth_context);
  4844. if (!r && !auth_context) {
  4845. r = krb5_auth_con_init(k5_context, &auth_context);
  4846. debug(F111,"k5_auth_is","krb5_auth_con_init",r);
  4847. }
  4848. #ifdef HEIMDAL
  4849. if (!r)
  4850. r = krb5_auth_con_setaddrs_from_fd(k5_context,
  4851. auth_context,
  4852. &ttyfd);
  4853. if (!r)
  4854. r = krb5_sock_to_principal(k5_context,
  4855. 0,
  4856. "host",
  4857. KRB5_NT_SRV_HST,
  4858. &server);
  4859. if (!r)
  4860. #else /* HEIMDAL */
  4861. if (!r) {
  4862. krb5_rcache rcache = NULL;
  4863. r = krb5_auth_con_getrcache(k5_context, auth_context,
  4864. &rcache);
  4865. debug(F111,"k5_auth_is","krb5_auth_con_getrcache",r);
  4866. if (!r && !rcache) {
  4867. /* Do not resolve server's principal name, we will check */
  4868. /* for validity after the krb5_rd_req() call. */
  4869. r = krb5_sname_to_principal(k5_context, 0, 0,
  4870. KRB5_NT_SRV_HST, &server);
  4871. debug(F111,"k5_auth_is","krb5_sname_to_principal",r);
  4872. if (!r) {
  4873. r = krb5_get_server_rcache(k5_context,
  4874. krb5_princ_component(k5_context, server, 0),
  4875. &rcache);
  4876. debug(F111,"k5_auth_is","krb5_get_server_rcache",r);
  4877. krb5_free_principal(k5_context, server);
  4878. }
  4879. }
  4880. if (!r) {
  4881. r = krb5_auth_con_setrcache(k5_context,
  4882. auth_context, rcache);
  4883. debug(F111,"k5_auth_is","krb5_auth_con_setrcache",r);
  4884. }
  4885. }
  4886. if (!r && k5_keytab) {
  4887. r = krb5_kt_resolve(k5_context,
  4888. k5_keytab, &keytabid);
  4889. debug(F111,"k5_auth_is","krb5_kt_resolve",r);
  4890. }
  4891. #endif /* HEIMDAL */
  4892. if (!r) {
  4893. r = krb5_rd_req(k5_context, &auth_context, &k5_auth,
  4894. #ifdef HEIMDAL
  4895. server, NULL, NULL,
  4896. #else /* HEIMDAL */
  4897. NULL, keytabid, NULL,
  4898. #endif /* HEIMDAL */
  4899. &k5_ticket);
  4900. debug(F111,"k5_auth_is","krb5_rd_req",r);
  4901. }
  4902. if (r) {
  4903. (void) ckstrncpy(errbuf, "krb5_rd_req failed: ",sizeof(errbuf));
  4904. (void) ckstrncat(errbuf, error_message(r),sizeof(errbuf));
  4905. goto errout;
  4906. }
  4907. #ifdef HEIMDAL
  4908. krb5_free_principal(k5_context, server);
  4909. {
  4910. char type_check[26];
  4911. /* UPDATE for START_TLS. AUTH_ENCRYPT_START_TLS and inclusion of */
  4912. /* client and then server finished messages. */
  4913. type_check[0] = AUTHTYPE_KERBEROS_V5;
  4914. type_check[1] = how; /* not broken into parts */
  4915. #ifdef CK_SSL
  4916. if ((how & AUTH_ENCRYPT_MASK) == AUTH_ENCRYPT_START_TLS) {
  4917. ssl_get_client_finished(&type_check[2],12);
  4918. ssl_get_server_finished(&type_check[14],12);
  4919. ckhexdump("k5_auth_is type_check",type_check,26);
  4920. }
  4921. #endif /* CK_SSL */
  4922. r = krb5_verify_authenticator_checksum(k5_context,
  4923. auth_context,
  4924. type_check,
  4925. #ifdef CK_SSL
  4926. ((how & AUTH_ENCRYPT_MASK) == AUTH_ENCRYPT_START_TLS) ? 26 :
  4927. #endif /* CK_SSL */
  4928. 2);
  4929. }
  4930. #else /* HEIMDAL */
  4931. len = krb5_princ_component(k5_context,k5_ticket->server,0)->length;
  4932. if (len < 256)
  4933. {
  4934. memcpy(princ,
  4935. krb5_princ_component(k5_context,k5_ticket->server,0)->data,
  4936. len);
  4937. princ[len] = '\0';
  4938. }
  4939. if ( strcmp((krb5_d_srv ? krb5_d_srv : KRB5_SERVICE_NAME), princ) )
  4940. {
  4941. debug(F110,"k5_auth_is incorrect service name",princ,0);
  4942. ckstrncpy(errbuf,"incorrect service name: ",sizeof(errbuf));
  4943. ckstrncat(errbuf,krb5_d_srv ? krb5_d_srv : KRB5_SERVICE_NAME,
  4944. sizeof(errbuf));
  4945. ckstrncat(errbuf," != ",sizeof(errbuf));
  4946. ckstrncat(errbuf,princ,sizeof(errbuf));
  4947. goto errout;
  4948. }
  4949. r = krb5_auth_con_getauthenticator(k5_context,
  4950. auth_context,
  4951. &authenticator);
  4952. debug(F111,"k5_auth_is","krb5_auth_con_getauthenticator",r);
  4953. if (r) {
  4954. (void) ckstrncpy(errbuf,
  4955. "krb5_auth_con_getauthenticator failed: ",
  4956. sizeof(errbuf)
  4957. );
  4958. (void) ckstrncat(errbuf, error_message(r),sizeof(errbuf));
  4959. goto errout;
  4960. }
  4961. if (authenticator->checksum) {
  4962. char type_check[26];
  4963. krb5_checksum *cksum = authenticator->checksum;
  4964. krb5_keyblock *key;
  4965. /* UPDATE for START_TLS. AUTH_ENCRYPT_START_TLS and inclusion of */
  4966. /* client and then server finished messages. */
  4967. type_check[0] = AUTHTYPE_KERBEROS_V5;
  4968. type_check[1] = how; /* not broken into parts */
  4969. #ifdef CK_SSL
  4970. if ((how & AUTH_ENCRYPT_MASK) == AUTH_ENCRYPT_START_TLS) {
  4971. ssl_get_client_finished(&type_check[2],12);
  4972. ssl_get_server_finished(&type_check[14],12);
  4973. ckhexdump("k5_auth_is type_check",type_check,26);
  4974. }
  4975. #endif /* CK_SSL */
  4976. r = krb5_auth_con_getkey(k5_context, auth_context,
  4977. &key);
  4978. debug(F111,"k5_auth_is","krb5_auth_con_getkey",r);
  4979. if (r) {
  4980. (void) ckstrncpy(errbuf, "krb5_auth_con_getkey failed: ",
  4981. sizeof(errbuf));
  4982. (void) ckstrncat(errbuf, error_message(r),sizeof(errbuf));
  4983. goto errout;
  4984. }
  4985. r = krb5_verify_checksum(k5_context,
  4986. cksum->checksum_type,
  4987. cksum,
  4988. &type_check,
  4989. ((how & AUTH_ENCRYPT_MASK) == AUTH_ENCRYPT_START_TLS) ? 26 :
  4990. 2,
  4991. key->contents,
  4992. key->length
  4993. );
  4994. debug(F111,"k5_auth_is","krb5_verify_checksum",r);
  4995. if (r) {
  4996. (void) ckstrncpy(errbuf,
  4997. "checksum verification failed: ",
  4998. sizeof(errbuf)
  4999. );
  5000. (void) ckstrncat(errbuf, error_message(r),sizeof(errbuf));
  5001. goto errout;
  5002. }
  5003. krb5_free_keyblock(k5_context, key);
  5004. } else {
  5005. if ((how & AUTH_ENCRYPT_MASK) == AUTH_ENCRYPT_USING_TELOPT) {
  5006. (void) strcpy(errbuf,
  5007. "authenticator is missing required checksum");
  5008. goto errout;
  5009. }
  5010. }
  5011. krb5_free_authenticator(k5_context, authenticator);
  5012. #endif /* HEIMDAL */
  5013. #ifdef TLS_VERIFY
  5014. if ((how & AUTH_ENCRYPT_MASK) == AUTH_ENCRYPT_START_TLS) {
  5015. krb5_data in, msg;
  5016. char tls_verify[24];
  5017. krb5_replay_data repdata;
  5018. ssl_get_server_finished(&tls_verify[0],12);
  5019. ssl_get_client_finished(&tls_verify[12],12);
  5020. in.data = tls_verify;
  5021. in.length = 24;
  5022. krb5_auth_con_genaddrs(k5_context, auth_context, ttyfd,
  5023. KRB5_AUTH_CONTEXT_GENERATE_LOCAL_FULL_ADDR);
  5024. if (r = krb5_mk_safe(k5_context,auth_context,&in,&msg,&repdata)) {
  5025. com_err("", r, "encoding tls verifier");
  5026. (void) ckstrncat(errbuf, error_message(r),sizeof(errbuf));
  5027. goto errout;
  5028. }
  5029. SendK5AuthSB(KRB5_TLS_VERIFY, msg.data, msg.length);
  5030. krb5_free_data_contents(k5_context,&msg);
  5031. }
  5032. #endif /* CK_SSL */
  5033. if ((how & AUTH_HOW_MASK) == AUTH_HOW_MUTUAL) {
  5034. /* do ap_rep stuff here */
  5035. if ((r = krb5_mk_rep(k5_context,
  5036. #ifdef HEIMDAL
  5037. &auth_context,
  5038. #else /* HEIMDAL */
  5039. auth_context,
  5040. #endif /* HEIMDAL */
  5041. &outbuf))) {
  5042. debug(F111,"k5_auth_is","krb5_mk_rep",r);
  5043. (void) ckstrncpy(errbuf, "Make reply failed: ",sizeof(errbuf));
  5044. (void) ckstrncat(errbuf, error_message(r),sizeof(errbuf));
  5045. goto errout;
  5046. }
  5047. debug(F111,"k5_auth_is","krb5_mk_rep",r);
  5048. SendK5AuthSB(KRB5_RESPONSE, outbuf.data, outbuf.length);
  5049. mutual_complete = 1;
  5050. }
  5051. #ifdef HEIMDAL
  5052. {
  5053. char * name = NULL;
  5054. if (krb5_unparse_name(k5_context, k5_ticket->client,
  5055. &name))
  5056. {
  5057. szUserNameAuthenticated[0] = '\0';
  5058. } else {
  5059. ckstrncpy(szUserNameAuthenticated,UIDBUFLEN,name);
  5060. free(name);
  5061. }
  5062. }
  5063. #else /* HEIMDAL */
  5064. if ( krb5_aname_to_localname(k5_context,
  5065. k5_ticket->enc_part2->client,
  5066. UIDBUFLEN,szUserNameAuthenticated) )
  5067. szUserNameAuthenticated[0] = '\0';
  5068. #endif /* HEIMDAL */
  5069. SendK5AuthSB(KRB_ACCEPT, szUserNameAuthenticated,
  5070. szUserNameAuthenticated[0] ? -1 : 0);
  5071. accept_complete = 1;
  5072. ckmakmsg(strTmp,sizeof(strTmp),
  5073. "Kerberos5 identifies him as ``",
  5074. szUserNameAuthenticated,"''",NULL);
  5075. printf("%s\r\n",strTmp);
  5076. if (szUserNameRequested[0] &&
  5077. krb5_kuserok(k5_context,
  5078. #ifdef HEIMDAL
  5079. k5_ticket->client,
  5080. #else /* HEIMDAL */
  5081. k5_ticket->enc_part2->client,
  5082. #endif /* HEIMDAL */
  5083. szUserNameRequested))
  5084. auth_finished(AUTH_VALID);
  5085. else
  5086. auth_finished(AUTH_USER);
  5087. krb5_auth_con_getremotesubkey(k5_context, auth_context,
  5088. &newkey);
  5089. if (k5_session_key) {
  5090. krb5_free_keyblock(k5_context, k5_session_key);
  5091. k5_session_key = 0;
  5092. }
  5093. if (newkey) {
  5094. krb5_copy_keyblock(k5_context, newkey, &k5_session_key);
  5095. krb5_free_keyblock(k5_context, newkey);
  5096. } else {
  5097. krb5_copy_keyblock(k5_context,
  5098. #ifdef HEIMDAL
  5099. &k5_ticket->ticket.key,
  5100. #else /* HEIMDAL */
  5101. k5_ticket->enc_part2->session,
  5102. #endif /* HEIMDAL */
  5103. &k5_session_key);
  5104. }
  5105. #ifdef CK_ENCRYPTION
  5106. #ifdef HEIMDAL
  5107. skey.type = k5_session_key->keyvalue.length == 8 ? SK_DES : SK_GENERIC;
  5108. skey.length = k5_session_key->keyvalue.length;
  5109. skey.data = k5_session_key->keyvalue.data;
  5110. #else /* HEIMDAL */
  5111. skey.type = k5_session_key->length == 8 ? SK_DES : SK_GENERIC;
  5112. skey.length = k5_session_key->length;
  5113. skey.data = k5_session_key->contents;
  5114. #endif /* HEIMDAL */
  5115. encrypt_session_key(&skey, AUTH_SERVER_TO_CLIENT);
  5116. #endif /* CK_ENCRYPTION */
  5117. debug(F100,"k5_auth_is AUTH_SUCCESS","",0);
  5118. krb5_errno = r;
  5119. if ( krb5_errno )
  5120. makestr(&krb5_errmsg,error_message(krb5_errno));
  5121. else
  5122. makestr(&krb5_errmsg,strTmp);
  5123. return AUTH_SUCCESS;
  5124. #ifdef FORWARD
  5125. case KRB5_FORWARD:
  5126. if ( !forward_flag ) {
  5127. SendK5AuthSB(KRB5_FORWARD_REJECT,
  5128. "forwarded credentials are being refused.",
  5129. -1);
  5130. return(AUTH_SUCCESS);
  5131. }
  5132. inbuf.length = cnt;
  5133. inbuf.data = (char *)data;
  5134. if (
  5135. #ifndef HEIMDAL
  5136. (!krb5_d_no_addresses &&
  5137. (r = krb5_auth_con_genaddrs(k5_context,auth_context,g_kstream->fd,
  5138. KRB5_AUTH_CONTEXT_GENERATE_REMOTE_FULL_ADDR))) ||
  5139. #endif /* HEIMDAL */
  5140. (r = rd_and_store_for_creds(k5_context, auth_context,&inbuf,
  5141. #ifdef HEIMDAL
  5142. k5_ticket->client
  5143. #else /* HEIMDAL */
  5144. k5_ticket->enc_part2->client
  5145. #endif /* HEIMDAL */
  5146. ))) {
  5147. (void) ckstrncpy(errbuf, "Read forwarded creds failed: ",
  5148. sizeof(errbuf));
  5149. (void) ckstrncat(errbuf, error_message(r),sizeof(errbuf));
  5150. SendK5AuthSB(KRB5_FORWARD_REJECT, errbuf, -1);
  5151. printf("Could not read forwarded credentials\r\n");
  5152. krb5_errno = r;
  5153. makestr(&krb5_errmsg,error_message(krb5_errno));
  5154. }
  5155. else {
  5156. SendK5AuthSB(KRB5_FORWARD_ACCEPT, 0, 0);
  5157. ckstrncpy(strTmp,"Forwarded credentials obtained",sizeof(strTmp));
  5158. printf("%s\r\n",strTmp);
  5159. krb5_errno = 0;
  5160. makestr(&krb5_errmsg,strTmp);
  5161. }
  5162. /* A failure to accept forwarded credentials is not an */
  5163. /* authentication failure. */
  5164. return AUTH_SUCCESS;
  5165. #endif /* FORWARD */
  5166. default:
  5167. printf("Unknown Kerberos option %d\r\n", data[-1]);
  5168. SendK5AuthSB(KRB_REJECT, 0, 0);
  5169. break;
  5170. }
  5171. auth_finished(AUTH_REJECT);
  5172. return AUTH_FAILURE;
  5173. errout:
  5174. SendK5AuthSB(KRB_REJECT, errbuf, -1);
  5175. krb5_errno = r;
  5176. makestr(&krb5_errmsg,errbuf);
  5177. printf("%s\r\n", errbuf);
  5178. if (auth_context) {
  5179. krb5_auth_con_free(k5_context, auth_context);
  5180. auth_context = 0;
  5181. }
  5182. auth_finished(AUTH_REJECT);
  5183. return AUTH_FAILURE;
  5184. }
  5185. #ifdef FORWARD
  5186. int
  5187. #ifdef CK_ANSIC
  5188. kerberos5_forward(void)
  5189. #else
  5190. kerberos5_forward()
  5191. #endif
  5192. {
  5193. krb5_error_code r;
  5194. krb5_ccache ccache=NULL;
  5195. krb5_principal client = 0;
  5196. krb5_principal server = 0;
  5197. krb5_data forw_creds;
  5198. #ifdef HEIMDAL
  5199. krb5_creds creds;
  5200. #endif /* HEIMDAL */
  5201. forw_creds.data = 0;
  5202. r = k5_get_ccache(k5_context,&ccache,NULL);
  5203. if ( r ) {
  5204. com_err(NULL, r, "Kerberos V5: could not get default ccache");
  5205. krb5_errno = r;
  5206. makestr(&krb5_errmsg,error_message(krb5_errno));
  5207. return(AUTH_FAILURE);
  5208. }
  5209. if ((r = krb5_cc_get_principal(k5_context, ccache, &client))) {
  5210. com_err(NULL, r, "Kerberos V5: could not get default principal");
  5211. goto cleanup;
  5212. }
  5213. #ifdef HEIMDAL
  5214. memset(&creds, 0, sizeof(creds));
  5215. creds.client = client;
  5216. if (r = krb5_build_principal(k5_context,
  5217. &creds.server,
  5218. strlen(client->realm),
  5219. client->realm,
  5220. "krbtgt",
  5221. client->realm,
  5222. NULL)) {
  5223. com_err(NULL, r, "Kerberos V5: could not get principal");
  5224. goto cleanup;
  5225. }
  5226. creds.times.endtime = 0;
  5227. if (r = krb5_get_forwarded_creds(k5_context,
  5228. auth_context,
  5229. ccache,
  5230. 0,
  5231. szHostName,
  5232. &creds,
  5233. &forw_creds)) {
  5234. com_err(NULL, r, "Kerberos V5: error getting forwarded creds");
  5235. goto cleanup;
  5236. }
  5237. #else /* HEIMDAL */
  5238. /* we should not need to make this call since we are storing the */
  5239. /* server's principal in fwd_server from our call to */
  5240. /* krb5_sname_to_principal() in k5_auth_send() */
  5241. if (fwd_server == NULL) {
  5242. if ((r = krb5_sname_to_principal(k5_context, szHostName,
  5243. krb5_d_srv ? krb5_d_srv : KRB5_SERVICE_NAME,
  5244. KRB5_NT_SRV_HST, &server))) {
  5245. com_err(NULL, r, "Kerberos V5: could not make server principal");
  5246. goto cleanup;
  5247. }
  5248. }
  5249. if (!krb5_d_no_addresses &&
  5250. (r = krb5_auth_con_genaddrs(k5_context, auth_context, g_kstream->fd,
  5251. KRB5_AUTH_CONTEXT_GENERATE_LOCAL_FULL_ADDR)))
  5252. {
  5253. com_err(NULL, r, "Kerberos V5: could not gen local full address");
  5254. goto cleanup;
  5255. }
  5256. if (r = krb5_fwd_tgt_creds(k5_context, auth_context, 0, client,
  5257. fwd_server ? fwd_server : server,
  5258. ccache, forwardable_flag, &forw_creds)) {
  5259. com_err(NULL, r, "Kerberos V5: error getting forwardable credentials");
  5260. goto cleanup;
  5261. }
  5262. #endif /* HEIMDAL */
  5263. /* Send forwarded credentials */
  5264. if (!SendK5AuthSB(KRB5_FORWARD, forw_creds.data, forw_creds.length)) {
  5265. printf("Kerberos V5 forwarding error!\r\n%s\r\n",
  5266. "Not enough room for authentication data");
  5267. }
  5268. cleanup:
  5269. if (client)
  5270. krb5_free_principal(k5_context, client);
  5271. if (server)
  5272. krb5_free_principal(k5_context, server);
  5273. #ifdef HEIMDAL
  5274. krb5_data_free(&forw_creds);
  5275. #else /* HEIMDAL */
  5276. krb5_free_data_contents(k5_context,&forw_creds);
  5277. #endif /* HEIMDAL */
  5278. krb5_cc_close(k5_context, ccache);
  5279. krb5_errno = r;
  5280. makestr(&krb5_errmsg,krb5_errno?error_message(krb5_errno):"OK");
  5281. return(r?AUTH_FAILURE:AUTH_SUCCESS);
  5282. }
  5283. #endif /* FORWARD */
  5284. #else /* KRB5 */
  5285. int
  5286. ck_krb5_autoget_TGT(char * dummy)
  5287. {
  5288. return(0);
  5289. }
  5290. #ifdef CK_KERBEROS
  5291. int
  5292. #ifdef CK_ANSIC
  5293. ck_krb5_initTGT( struct krb_op_data * op, struct krb5_init_data * init,
  5294. struct krb4_init_data * k4_init)
  5295. #else
  5296. ck_krb5_initTGT(op,init,k4_init)
  5297. krb_op_data * op; struct krb5_init_data * init;
  5298. struct krb4_init_data * k4_init;
  5299. #endif /* CK_ANSIC*/
  5300. {
  5301. return(-1);
  5302. }
  5303. int
  5304. #ifdef CK_ANSIC
  5305. ck_krb5_destroy(struct krb_op_data * op)
  5306. #else
  5307. ck_krb5_destroy(op) struct krb_op_data * op;
  5308. #endif
  5309. {
  5310. return(-1);
  5311. }
  5312. int
  5313. #ifdef CK_ANSIC
  5314. ck_krb5_list_creds(struct krb_op_data * op, struct krb5_list_cred_data * lc)
  5315. #else
  5316. ck_krb5_list_creds(op,lc)
  5317. struct krb_op_data * op; struct krb5_list_cred_data * lc;
  5318. #endif
  5319. {
  5320. return(-1);
  5321. }
  5322. #else /* CK_KERBEROS */
  5323. int
  5324. #ifdef CK_ANSIC
  5325. ck_krb5_initTGT(void * op, void * init, void * k4_init )
  5326. #else
  5327. ck_krb5_initTGT(op,init,k4_init)
  5328. void * op; void * init; void * k4_init;
  5329. #endif /* CK_ANSIC*/
  5330. {
  5331. return(-1);
  5332. }
  5333. int
  5334. #ifdef CK_ANSIC
  5335. ck_krb5_destroy(void * op)
  5336. #else
  5337. ck_krb5_destroy(op) void * op;
  5338. #endif
  5339. {
  5340. return(-1);
  5341. }
  5342. int
  5343. #ifdef CK_ANSIC
  5344. ck_krb5_list_creds(void * op, void * lc)
  5345. #else
  5346. ck_krb5_list_creds(op,lc)
  5347. void * op; void * lc;
  5348. #endif
  5349. {
  5350. return(-1);
  5351. }
  5352. #endif /* CK_KERBEROS */
  5353. #endif /* KRB5 */
  5354. #ifdef GSSAPI_KRB5
  5355. /*
  5356. *
  5357. * gssk5_auth_send - gets authentication bits we need to send to KDC.
  5358. *
  5359. * Result is left in k5_auth
  5360. *
  5361. * Returns: 0 on failure, 1 on success
  5362. *
  5363. */
  5364. static int
  5365. #ifdef CK_ANSIC
  5366. gssk5_auth_send(int how, int encrypt, int forward)
  5367. #else
  5368. gssk5_auth_send(how,encrypt,forward) int how; int encrypt; int forward;
  5369. #endif
  5370. {
  5371. OM_uint32 maj_stat, min_stat;
  5372. #ifdef KRB5
  5373. char * realm = NULL;
  5374. char tgt[256];
  5375. #endif /* KRB5 */
  5376. gss_chan.initiator_addrtype = GSS_C_AF_INET; /* OM_uint32 */
  5377. gss_chan.initiator_address.length = 4;
  5378. gss_chan.initiator_address.value = &myctladdr.sin_addr.s_addr;
  5379. gss_chan.acceptor_addrtype = GSS_C_AF_INET; /* OM_uint32 */
  5380. gss_chan.acceptor_address.length = 4;
  5381. gss_chan.acceptor_address.value = &hisctladdr.sin_addr.s_addr;
  5382. gss_chan.application_data.length = 0;
  5383. gss_chan.application_data.value = 0;
  5384. #ifdef KRB5
  5385. realm = ck_krb5_realmofhost(ftp_host);
  5386. if (realm) {
  5387. ckmakmsg(tgt,sizeof(tgt),"krbtgt/",realm,"@",realm);
  5388. debug(F110,"ftp_auth(GSSAPI) TGT",tgt,0);
  5389. if ( krb5_autoget &&
  5390. !((ck_krb5_tkt_isvalid(NULL,tgt) > 0) ||
  5391. (ck_krb5_is_tgt_valid() > 0)) )
  5392. ck_krb5_autoget_TGT(realm);
  5393. }
  5394. #endif /* KRB5 */
  5395. /* Blob from gss-client */
  5396. /* host@hostname */
  5397. /* the V5 GSSAPI binding canonicalizes this for us... */
  5398. ckmakmsg(gss_stbuf,GSS_BUFSIZ,
  5399. krb5_d_srv ? krb5_d_srv : KRB5_SERVICE_NAME,
  5400. "@",
  5401. szHostName,
  5402. NULL
  5403. );
  5404. fprintf(stderr, "Authenticating to <%s>...\n", gss_stbuf);
  5405. gss_send_tok.value = gss_stbuf;
  5406. gss_send_tok.length = strlen(gss_stbuf);
  5407. maj_stat = gss_import_name(&min_stat, &gss_send_tok,
  5408. gss_nt_service_name,
  5409. &gss_target_name
  5410. );
  5411. if (maj_stat != GSS_S_COMPLETE) {
  5412. user_gss_error(maj_stat, min_stat, "parsing name");
  5413. secure_error("name parsed <%s>\n", gss_stbuf);
  5414. return(0);
  5415. }
  5416. token_ptr = GSS_C_NO_BUFFER;
  5417. gcontext = GSS_C_NO_CONTEXT; /* structure copy */
  5418. fprintf(stderr, "calling gss_init_sec_context\n");
  5419. maj_stat =
  5420. gss_init_sec_context(&min_stat,
  5421. GSS_C_NO_CREDENTIAL,
  5422. &gcontext,
  5423. gss_target_name,
  5424. gss_mech_krb5,
  5425. GSS_C_MUTUAL_FLAG |
  5426. GSS_C_REPLAY_FLAG |
  5427. ((forward && forward_flag) ?
  5428. GSS_C_DELEG_FLAG : 0),
  5429. 0,
  5430. (krb5_d_no_addresses ? /* channel bindings */
  5431. GSS_C_NO_CHANNEL_BINDINGS :
  5432. &gss_chan),
  5433. gss_token_ptr,
  5434. NULL, /* ignore mech type */
  5435. &gss_send_tok,
  5436. NULL, /* ignore ret_flags */
  5437. NULL
  5438. ); /* ignore time_rec */
  5439. if (maj_stat != GSS_S_COMPLETE &&
  5440. maj_stat != GSS_S_CONTINUE_NEEDED) {
  5441. user_gss_error(maj_stat,
  5442. min_stat,
  5443. "initializing context"
  5444. );
  5445. gss_release_name(&min_stat, &gss_target_name);
  5446. return(0);
  5447. }
  5448. return(1);
  5449. }
  5450. /*
  5451. * gssk5_auth_reply -- checks the reply for mutual authentication.
  5452. */
  5453. static int
  5454. #ifdef CK_ANSIC
  5455. gssk5_auth_reply(int how, unsigned char *data, int cnt)
  5456. #else
  5457. gssk5_auth_reply(how,data,cnt) int how; unsigned char *data; int cnt;
  5458. #endif
  5459. {
  5460. data += 4; /* Point to status byte */
  5461. cnt -=5;
  5462. switch (*data++) {
  5463. case GSS_REJECT:
  5464. if (cnt > 0) {
  5465. char *s;
  5466. int len;
  5467. ckstrncpy(strTmp,"GSSAPI refuses authentication because\r\n",
  5468. sizeof(strTmp));
  5469. len = strlen(strTmp);
  5470. if ( len + cnt < sizeof(strTmp) ) {
  5471. s = strTmp + strlen(strTmp);
  5472. memcpy(s, data, cnt); /* safe */
  5473. s[cnt] = 0;
  5474. }
  5475. } else
  5476. ckstrncpy(strTmp,"GSSAPI refuses authentication",
  5477. sizeof(strTmp));
  5478. printf("GSSAPI authentication failed!\r\n%s\r\n",strTmp);
  5479. auth_finished(AUTH_REJECT);
  5480. return AUTH_FAILURE;
  5481. case GSS_ACCEPT:
  5482. if ( cnt > 0 ) {
  5483. char *s;
  5484. int len;
  5485. ckstrncpy(strTmp,"GSSAPI accepts you as ",sizeof(strTmp));
  5486. len = strlen(strTmp);
  5487. if ( len + cnt < sizeof(strTmp) ) {
  5488. s = strTmp + strlen(strTmp);
  5489. memcpy(s,data,cnt);
  5490. s[cnt] = 0;
  5491. }
  5492. }
  5493. accept_complete = 1;
  5494. printf("%s\r\n",strTmp);
  5495. auth_finished(AUTH_USER);
  5496. return AUTH_SUCCESS;
  5497. case GSS_RESPONSE:
  5498. gss_token_ptr = &gss_recv_tok;
  5499. gss_recv_tok.value = data;
  5500. gss_recv_tok.length = cnt;
  5501. maj_stat =
  5502. gss_init_sec_context(&min_stat,
  5503. GSS_C_NO_CREDENTIAL,
  5504. &gcontext,
  5505. gss_target_name,
  5506. gss_krb5_mech,
  5507. GSS_C_MUTUAL_FLAG |
  5508. GSS_C_REPLAY_FLAG |
  5509. (forward_flag ?
  5510. GSS_C_DELEG_FLAG : 0),
  5511. 0,
  5512. (krb5_d_no_addresses ? /* channel bindings */
  5513. GSS_C_NO_CHANNEL_BINDINGS :
  5514. &gss_chan),
  5515. gss_token_ptr,
  5516. NULL, /* ignore mech type */
  5517. &gss_send_tok,
  5518. NULL, /* ignore ret_flags */
  5519. NULL
  5520. ); /* ignore time_rec */
  5521. if ( maj_stat == GSS_S_COMPLETE )
  5522. {
  5523. } else if ( maj_stat == CSS_S_CONTINUE_NEEDED ) {
  5524. } else {
  5525. }
  5526. ckstrncpy(strTmp,"Remote machine has been mutually authenticated",
  5527. sizeof(strTmp));
  5528. printf("%s\r\n",strTmp);
  5529. auth_finished(AUTH_USER);
  5530. return AUTH_SUCCESS;
  5531. default:
  5532. auth_finished(AUTH_REJECT);
  5533. return AUTH_FAILURE; /* Unknown reply type */
  5534. }
  5535. }
  5536. /*
  5537. *
  5538. * gssk5_auth_is.
  5539. *
  5540. */
  5541. static int
  5542. #ifdef CK_ANSIC
  5543. k5_auth_is(int how, unsigned char *data, int cnt)
  5544. #else
  5545. k5_auth_is(how,data,cnt) int how; unsigned char *data; int cnt;
  5546. #endif
  5547. {
  5548. int replied = 0;
  5549. gss_cred_id_t server_creds, deleg_creds;
  5550. gss_name_t client;
  5551. int ret_flags;
  5552. gss_buffer_desc name_buf;
  5553. gss_name_t server_name;
  5554. OM_uint32 acquire_maj,
  5555. acquire_min,
  5556. accept_maj,
  5557. accept_min,
  5558. stat_maj,
  5559. stat_min;
  5560. gss_OID mechid;
  5561. gss_buffer_desc tok, out_tok;
  5562. char gbuf[GSS_BUFSIZ];
  5563. u_char gout_buf[GSS_BUFSIZ];
  5564. char localname[MAXHOSTNAMELEN];
  5565. char service_name[MAXHOSTNAMELEN+10];
  5566. char **service;
  5567. struct hostent *hp;
  5568. data += 4; /* Point to status byte */
  5569. cnt -= 4;
  5570. ckhexdump("gssk5_auth_is data",data,cnt);
  5571. debug(F111,"gssk5_auth_is","how",how);
  5572. if (cnt-- < 1) {
  5573. auth_finished(AUTH_REJECT);
  5574. return AUTH_FAILURE;
  5575. }
  5576. switch (*data++) {
  5577. case GSS_AUTH:
  5578. gss_chan.initiator_addrtype = GSS_C_AF_INET;
  5579. gss_chan.initiator_address.length = 4;
  5580. gss_chan.initiator_address.value = &his_addr.sin_addr.s_addr;
  5581. gss_chan.acceptor_addrtype = GSS_C_AF_INET;
  5582. gss_chan.acceptor_address.length = 4;
  5583. gss_chan.acceptor_address.value = &ctrl_addr.sin_addr.s_addr;
  5584. gss_chan.application_data.length = 0;
  5585. gss_chan.application_data.value = 0;
  5586. tok.value = data;
  5587. tok.length = cnt;
  5588. if (gethostname(localname, MAXHOSTNAMELEN)) {
  5589. auth_finished(AUTH_REJECT);
  5590. return AUTH_FAILURE;
  5591. }
  5592. if (!(hp = gethostbyname(localname))) {
  5593. auth_finished(AUTH_REJECT);
  5594. return AUTH_FAILURE;
  5595. }
  5596. #ifdef HADDRLIST
  5597. hp = ck_copyhostent(hp);
  5598. #endif /* HADDRLIST */
  5599. strncpy(localname, hp->h_name, sizeof(localname) - 1);
  5600. localname[sizeof(localname) - 1] = '\0';
  5601. sprintf(service_name, "%s@%s", *service, localname);
  5602. name_buf.value = service_name;
  5603. name_buf.length = strlen(name_buf.value) + 1;
  5604. stat_maj = gss_import_name(&stat_min, &name_buf,
  5605. gss_nt_service_name,
  5606. &server_name);
  5607. if (stat_maj != GSS_S_COMPLETE) {
  5608. auth_finished(AUTH_REJECT);
  5609. return AUTH_FAILURE;
  5610. }
  5611. acquire_maj = gss_acquire_cred(&acquire_min, server_name, 0,
  5612. GSS_C_NULL_OID_SET, GSS_C_ACCEPT,
  5613. &server_creds, NULL, NULL);
  5614. (void) gss_release_name(&stat_min, &server_name);
  5615. if (acquire_maj != GSS_S_COMPLETE) {
  5616. reply_gss_error(535, accept_maj, accept_min,
  5617. "accepting context");
  5618. syslog(LOG_ERR, "failed accepting context");
  5619. (void) gss_release_cred(&stat_min, &server_creds);
  5620. if (ret_flags & GSS_C_DELEG_FLAG)
  5621. (void) gss_release_cred(&stat_min,
  5622. &deleg_creds);
  5623. return 0;
  5624. }
  5625. gcontext = GSS_C_NO_CONTEXT;
  5626. accept_maj = gss_accept_sec_context(&accept_min,
  5627. &gcontext, /* context_handle */
  5628. /* verifier_cred_handle */
  5629. server_creds,
  5630. &tok, /* input_token */
  5631. (krb5_d_no_addresses ?
  5632. /* channel bindings */
  5633. GSS_C_NO_CHANNEL_BINDINGS :
  5634. &gss_chan),
  5635. &client, /* src_name */
  5636. &mechid, /* mech_type */
  5637. &out_tok, /* output_token */
  5638. &ret_flags,
  5639. NULL, /* ignore time_rec */
  5640. /* forwarded credentials */
  5641. &deleg_creds
  5642. );
  5643. if (accept_maj!=GSS_S_COMPLETE && accept_maj!=GSS_S_CONTINUE_NEEDED) {
  5644. reply_gss_error(535, accept_maj, accept_min,
  5645. "accepting context");
  5646. syslog(LOG_ERR, "failed accepting context");
  5647. (void) gss_release_cred(&stat_min, &server_creds);
  5648. if (ret_flags & GSS_C_DELEG_FLAG)
  5649. (void) gss_release_cred(&stat_min,
  5650. &deleg_creds);
  5651. return 0;
  5652. }
  5653. if (out_tok.length) {
  5654. if (kerror = radix_encode(out_tok.value,gbuf,&out_tok.length, 0)) {
  5655. secure_error("Couldn't encode ADAT reply (%s)",
  5656. radix_error(kerror));
  5657. syslog(LOG_ERR, "couldn't encode ADAT reply");
  5658. (void) gss_release_cred(&stat_min, &server_creds);
  5659. if (ret_flags & GSS_C_DELEG_FLAG)
  5660. (void) gss_release_cred(&stat_min,
  5661. &deleg_creds);
  5662. return(0);
  5663. }
  5664. if (stat_maj == GSS_S_COMPLETE) {
  5665. reply(235, "ADAT=%s", gbuf);
  5666. replied = 1;
  5667. } else {
  5668. /* If the server accepts the security data, and
  5669. requires additional data, it should respond
  5670. with reply code 335. */
  5671. reply(335, "ADAT=%s", gbuf);
  5672. }
  5673. (void) gss_release_buffer(&stat_min, &out_tok);
  5674. }
  5675. if (stat_maj == GSS_S_COMPLETE) {
  5676. /* GSSAPI authentication succeeded */
  5677. stat_maj = gss_display_name(&stat_min, client,
  5678. &client_name, &mechid);
  5679. if (stat_maj != GSS_S_COMPLETE) {
  5680. /* "If the server rejects the security data (if
  5681. a checksum fails, for instance), it should
  5682. respond with reply code 535." */
  5683. reply_gss_error(535, stat_maj, stat_min,
  5684. "extracting GSSAPI identity name");
  5685. syslog(LOG_ERR, "gssapi error extracting identity");
  5686. (void) gss_release_cred(&stat_min, &server_creds);
  5687. if (ret_flags & GSS_C_DELEG_FLAG)
  5688. (void) gss_release_cred(&stat_min,
  5689. &deleg_creds);
  5690. return 0;
  5691. }
  5692. auth_type = temp_auth_type;
  5693. temp_auth_type = NULL;
  5694. (void) gss_release_cred(&stat_min, &server_creds);
  5695. if (ret_flags & GSS_C_DELEG_FLAG) {
  5696. if (want_creds)
  5697. ftpd_gss_convert_creds(client_name.value,
  5698. deleg_creds);
  5699. (void) gss_release_cred(&stat_min, &deleg_creds);
  5700. }
  5701. /* If the server accepts the security data, but does
  5702. not require any additional data (i.e., the security
  5703. data exchange has completed successfully), it must
  5704. respond with reply code 235. */
  5705. if (!replied)
  5706. {
  5707. if (ret_flags & GSS_C_DELEG_FLAG && !have_creds)
  5708. reply(235,
  5709. "GSSAPI Authentication succeeded, but could not accept forwarded credentials"
  5710. );
  5711. else
  5712. reply(235, "GSSAPI Authentication succeeded");
  5713. }
  5714. return(1);
  5715. } else if (stat_maj == GSS_S_CONTINUE_NEEDED) {
  5716. /* If the server accepts the security data, and
  5717. requires additional data, it should respond with
  5718. reply code 335. */
  5719. reply(335, "more data needed");
  5720. (void) gss_release_cred(&stat_min, &server_creds);
  5721. if (ret_flags & GSS_C_DELEG_FLAG)
  5722. (void) gss_release_cred(&stat_min, &deleg_creds);
  5723. return(0);
  5724. } else {
  5725. /* "If the server rejects the security data (if
  5726. a checksum fails, for instance), it should
  5727. respond with reply code 535." */
  5728. reply_gss_error(535, stat_maj, stat_min,
  5729. "GSSAPI failed processing ADAT");
  5730. syslog(LOG_ERR, "GSSAPI failed processing ADAT");
  5731. (void) gss_release_cred(&stat_min, &server_creds);
  5732. if (ret_flags & GSS_C_DELEG_FLAG)
  5733. (void) gss_release_cred(&stat_min, &deleg_creds);
  5734. return(0);
  5735. }
  5736. debug(F100,"gssk5_auth_is AUTH_SUCCESS","",0);
  5737. krb5_errno = r;
  5738. if ( krb5_errno )
  5739. makestr(&krb5_errmsg,error_message(krb5_errno));
  5740. else
  5741. makestr(&krb5_errmsg,strTmp);
  5742. return AUTH_SUCCESS;
  5743. default:
  5744. printf("Unknown Kerberos option %d\r\n", data[-1]);
  5745. SendGSSK5AuthSB(GSS_REJECT, 0, 0);
  5746. break;
  5747. }
  5748. auth_finished(AUTH_REJECT);
  5749. return AUTH_FAILURE;
  5750. }
  5751. #endif /* GSSAPI_KRB5 */
  5752. #ifdef CK_SRP
  5753. /*
  5754. * Copyright (c) 1997 Stanford University
  5755. *
  5756. * The use of this software for revenue-generating purposes may require a
  5757. * license from the owners of the underlying intellectual property.
  5758. * Specifically, the SRP-3 protocol may not be used for revenue-generating
  5759. * purposes without a license.
  5760. *
  5761. * NOTE: Columbia University has a license.
  5762. *
  5763. * Within that constraint, permission to use, copy, modify, and distribute
  5764. * this software and its documentation for any purpose is hereby granted
  5765. * without fee, provided that the above copyright notices and this permission
  5766. * notice appear in all copies of the software and related documentation.
  5767. *
  5768. * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND,
  5769. * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY
  5770. * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
  5771. *
  5772. * IN NO EVENT SHALL STANFORD BE LIABLE FOR ANY SPECIAL, INCIDENTAL,
  5773. * INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, OR ANY DAMAGES WHATSOEVER
  5774. * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER OR NOT ADVISED OF
  5775. * THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF LIABILITY, ARISING OUT
  5776. * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  5777. */
  5778. static void
  5779. srp_encode_length(data, num)
  5780. unsigned char * data;
  5781. int num;
  5782. {
  5783. *data = (num >> 8) & 0xff;
  5784. *++data = num & 0xff;
  5785. }
  5786. static int
  5787. srp_decode_length(data)
  5788. unsigned char * data;
  5789. {
  5790. return (((int) *data & 0xff) << 8) | (*(data + 1) & 0xff);
  5791. }
  5792. #ifdef PRE_SRP_1_7_3
  5793. static int
  5794. #ifdef CK_ANSIC
  5795. srp_reply(int how, unsigned char *data, int cnt)
  5796. #else
  5797. srp_reply(how,data,cnt) int how; unsigned char *data; int cnt;
  5798. #endif
  5799. {
  5800. struct t_num n;
  5801. struct t_num g;
  5802. struct t_num s;
  5803. struct t_num B;
  5804. struct t_num * A;
  5805. char type_check[26];
  5806. int pflag;
  5807. #ifdef CK_ENCRYPTION
  5808. Session_Key skey;
  5809. #endif /* ENCRYPTION */
  5810. char * str=NULL;
  5811. data += 4; /* Point to status byte */
  5812. cnt -= 4;
  5813. if(cnt-- < 1) {
  5814. auth_finished(AUTH_REJECT);
  5815. return AUTH_FAILURE;
  5816. }
  5817. switch(*data++) {
  5818. case SRP_REJECT:
  5819. ckmakmsg(strTmp,sizeof(strTmp),
  5820. "SRP refuses authentication for '",szUserName,
  5821. "'\r\n",NULL);
  5822. if (cnt > 0) {
  5823. int len = strlen(strTmp);
  5824. if ( len + cnt < sizeof(strTmp) ) {
  5825. str = strTmp + strlen(strTmp);
  5826. memcpy(str,data,cnt);
  5827. str[cnt] = 0;
  5828. }
  5829. }
  5830. printf("SRP authentication failed!\r\n%s\r\n",strTmp);
  5831. if (tc != NULL) {
  5832. t_clientclose(tc);
  5833. tc = NULL;
  5834. }
  5835. auth_finished(AUTH_REJECT);
  5836. return AUTH_FAILURE;
  5837. case SRP_ACCEPT:
  5838. if(cnt < RESPONSE_LEN || !srp_waitresp ||
  5839. tc == NULL
  5840. ) {
  5841. printf("SRP Protocol error\r\n");
  5842. return(auth_resend(AUTHTYPE_SRP));
  5843. }
  5844. srp_waitresp = 0;
  5845. if(t_clientverify(tc, data) == 0) {
  5846. printf("SRP accepts you as %s\r\n",szUserName);
  5847. #ifdef CK_SSL
  5848. if((ssl_active_flag || tls_active_flag) &&
  5849. (how & AUTH_ENCRYPT_MASK) == AUTH_ENCRYPT_START_TLS) {
  5850. printf("TLS session parameters verified by SRP\r\n");
  5851. } else
  5852. #endif /* CK_SSL */
  5853. #ifdef CK_ENCRYPTION
  5854. {
  5855. skey.type = SK_GENERIC;
  5856. skey.length = SESSION_KEY_LEN;
  5857. skey.data = tc->session_key;
  5858. encrypt_session_key(&skey, AUTH_CLIENT_TO_SERVER);
  5859. }
  5860. #endif /* ENCRYPTION */
  5861. t_clientclose(tc);
  5862. tc = NULL;
  5863. accept_complete = 1;
  5864. auth_finished(AUTH_VALID);
  5865. return AUTH_SUCCESS;
  5866. } else {
  5867. printf("SRP server authentication failed!\r\n");
  5868. t_clientclose(tc);
  5869. tc = NULL;
  5870. return(auth_resend(AUTHTYPE_SRP));
  5871. }
  5872. break;
  5873. case SRP_PARAMS:
  5874. if(!szUserName) {
  5875. printf("No username available\r\n");
  5876. return(auth_resend(AUTHTYPE_SRP));
  5877. }
  5878. n.len = srp_decode_length(data);
  5879. data += 2;
  5880. cnt -= 2;
  5881. if(n.len > cnt) {
  5882. printf("n too long\r\n");
  5883. return(auth_resend(AUTHTYPE_SRP));
  5884. }
  5885. n.data = data;
  5886. data += n.len;
  5887. cnt -= n.len;
  5888. g.len = srp_decode_length(data);
  5889. data += 2;
  5890. cnt -= 2;
  5891. if(g.len > cnt) {
  5892. printf("g too long\r\n");
  5893. return(auth_resend(AUTHTYPE_SRP));
  5894. }
  5895. g.data = data;
  5896. data += g.len;
  5897. cnt -= g.len;
  5898. s.len = srp_decode_length(data);
  5899. data += 2;
  5900. cnt -= 2;
  5901. if(s.len > cnt) {
  5902. printf("salt too long\r\n");
  5903. return(auth_resend(AUTHTYPE_SRP));
  5904. }
  5905. s.data = data;
  5906. data += s.len;
  5907. cnt -= s.len;
  5908. /* If the parameters provided by the server cannot be
  5909. * validated the following function will fail.
  5910. */
  5911. tc = t_clientopen(szUserName, &n, &g, &s);
  5912. if (tc == NULL) {
  5913. printf("SRP parameter initialization error\r\n");
  5914. return(auth_resend(AUTHTYPE_SRP));
  5915. }
  5916. A = t_clientgenexp(tc);
  5917. if(A == NULL) {
  5918. printf("SRP protocol error\r\n");
  5919. return(auth_resend(AUTHTYPE_SRP));
  5920. }
  5921. SendSRPAuthSB(SRP_EXP, A->data, A->len);
  5922. if ( pwbuf[0] && pwflg ) {
  5923. printf("SRP using %d-bit modulus for '%s'\r\n",
  5924. 8 * n.len,
  5925. szUserName
  5926. );
  5927. ckstrncpy(srp_passwd,pwbuf,sizeof(srp_passwd));
  5928. #ifdef OS2
  5929. if ( pwcrypt )
  5930. ck_encrypt((char *)srp_passwd);
  5931. #endif /* OS2 */
  5932. } else {
  5933. extern char * srppwprompt;
  5934. char preface[128];
  5935. int ok;
  5936. if (srppwprompt && srppwprompt[0] &&
  5937. (strlen(srppwprompt) + strlen(szUserName) - 2) <
  5938. sizeof(preface)) {
  5939. sprintf(preface,srppwprompt,szUserName);
  5940. } else {
  5941. ckmakxmsg( preface,sizeof(preface),
  5942. "SRP using ",ckitoa(8*n.len),"-bit modulus for '",
  5943. szUserName, "'", NULL, NULL, NULL, NULL, NULL,
  5944. NULL, NULL);
  5945. }
  5946. ok = uq_txt( preface,"Password: ",2,NULL,
  5947. srp_passwd,sizeof(srp_passwd)-1,NULL,
  5948. DEFAULT_UQ_TIMEOUT);
  5949. if ( !ok )
  5950. srp_passwd[0] = '\0';
  5951. }
  5952. t_clientpasswd(tc, srp_passwd);
  5953. memset(srp_passwd, 0, sizeof(srp_passwd));
  5954. return AUTH_SUCCESS;
  5955. case SRP_CHALLENGE:
  5956. if(tc == NULL) {
  5957. printf("SRP protocol error\r\n");
  5958. return(auth_resend(AUTHTYPE_SRP));
  5959. }
  5960. #ifndef PRE_SRP_1_4_5
  5961. /*
  5962. * The original SRP AUTH implementation did not protect against
  5963. * tampering of the auth-type-pairs. Therefore, when the
  5964. * AUTH_ENCRYPT_MASK bits are zero, no extra data is inserted
  5965. * into the SRP hash computation. When AUTH_ENCRYPT_START_TLS
  5966. * is set we also insert the SSL/TLS client and server finished
  5967. * messages to ensure that there is no man in the middle attack
  5968. * underway on the SSL/TLS connection.
  5969. */
  5970. if ((how & AUTH_ENCRYPT_MASK) != AUTH_ENCRYPT_OFF) {
  5971. type_check[0] = AUTHTYPE_SRP;
  5972. type_check[1] = how;
  5973. #ifdef CK_SSL
  5974. if ((how & AUTH_ENCRYPT_MASK) == AUTH_ENCRYPT_START_TLS) {
  5975. ssl_get_client_finished(&type_check[2],12);
  5976. ssl_get_server_finished(&type_check[14],12);
  5977. t_clientaddexdata(tc,type_check,26);
  5978. } else
  5979. #endif /* CK_SSL */
  5980. t_clientaddexdata(tc,type_check,2);
  5981. }
  5982. #endif /* PRE_SRP_1_4_5 */
  5983. B.data = data;
  5984. B.len = cnt;
  5985. t_clientgetkey(tc, &B);
  5986. SendSRPAuthSB(SRP_RESPONSE, t_clientresponse(tc), RESPONSE_LEN);
  5987. srp_waitresp = 1;
  5988. return AUTH_SUCCESS;
  5989. default:
  5990. return(auth_resend(AUTHTYPE_SRP));
  5991. }
  5992. return AUTH_FAILURE;
  5993. }
  5994. static int
  5995. #ifdef CK_ANSIC
  5996. srp_is(int how, unsigned char *data, int cnt)
  5997. #else
  5998. srp_is(how,data,cnt) int how; unsigned char *data; int cnt;
  5999. #endif
  6000. {
  6001. char * pbuf = NULL;
  6002. char * ptr;
  6003. #ifdef CK_ENCRYPTION
  6004. Session_Key skey;
  6005. #endif
  6006. struct t_num A;
  6007. struct t_pw * tpw = NULL;
  6008. struct t_conf * tconf = NULL;
  6009. struct passwd * pass;
  6010. static struct t_num * B = NULL; /* Holder for B */
  6011. #ifdef CK_SSL
  6012. char type_check[26];
  6013. #else
  6014. char type_check[2];
  6015. #endif /* CK_SSL */
  6016. if ((cnt -= 4) < 1) {
  6017. auth_finished(AUTH_REJECT);
  6018. return AUTH_FAILURE;
  6019. }
  6020. data += 4;
  6021. cnt -= 1;
  6022. switch(*data++) {
  6023. case SRP_AUTH:
  6024. /* Send parameters back to client */
  6025. if(ts != NULL) {
  6026. t_serverclose(ts);
  6027. ts = NULL;
  6028. }
  6029. if(!szUserNameRequested[0]) {
  6030. if (1)
  6031. printf("No username available\r\n");
  6032. SendSRPAuthSB(SRP_REJECT, (void *) "No username supplied", -1);
  6033. auth_finished(AUTH_REJECT);
  6034. return(AUTH_FAILURE);
  6035. }
  6036. #ifdef IKSD
  6037. #ifdef CK_LOGIN
  6038. if (inserver && ckxanon &&
  6039. !strcmp(szUserNameRequested,"anonymous")) {
  6040. SendSRPAuthSB(SRP_REJECT, (void *)
  6041. "anonymous login cannot be performed with Secure Remote Password",
  6042. -1);
  6043. auth_finished(AUTH_REJECT);
  6044. return(AUTH_FAILURE);
  6045. }
  6046. #endif /* CK_LOGIN */
  6047. #endif /* IKSD */
  6048. #ifndef PRE_SRP_1_4_4
  6049. if(tpw == NULL) {
  6050. if((tpw = t_openpw(NULL)) == NULL) {
  6051. if (1)
  6052. printf("Unable to open password file\r\n");
  6053. SendSRPAuthSB(SRP_REJECT, (void *) "No password file", -1);
  6054. return(AUTH_FAILURE);
  6055. }
  6056. }
  6057. if(tconf == NULL) {
  6058. if((tconf = t_openconf(NULL)) == NULL) {
  6059. if (1)
  6060. printf("Unable to open configuration file\r\n");
  6061. SendSRPAuthSB(SRP_REJECT, (void *)"No configuration file", -1);
  6062. return(AUTH_FAILURE);
  6063. }
  6064. }
  6065. ts = t_serveropenfromfiles(szUserNameRequested, tpw, tconf);
  6066. t_closepw(tpw);
  6067. tpw = NULL;
  6068. t_closeconf(tconf);
  6069. tconf = NULL;
  6070. #else /* PRE_SRP_1_4_4 */
  6071. #ifdef COMMENT
  6072. /* the code in this block should no longer be necessary on OS/2
  6073. or Windows because I have added functionality to libsrp.lib
  6074. to find the srp files. 4/22/2000
  6075. */
  6076. /* On Windows and OS/2 there is no well defined place for the */
  6077. /* ETC directory. So we look for either an SRP_ETC or ETC */
  6078. /* environment variable in that order. If we find one we */
  6079. /* attempt to open the files manually. */
  6080. /* We will reuse the strTmp[] for the file names. */
  6081. ptr = getenv("SRP_ETC");
  6082. if ( !ptr )
  6083. ptr = getenv("ETC");
  6084. #ifdef NT
  6085. if ( !ptr ) {
  6086. DWORD len;
  6087. len = AUTHTMPBL;
  6088. len = GetWindowsDirectory(strTmp,len);
  6089. if ( len > 0 && len < AUTHTMPBL) {
  6090. if ( !isWin95() ) {
  6091. if ( len == 1 )
  6092. ckstrncat(strTmp,"SYSTEM32/DRIVERS/ETC",sizeof(strTmp));
  6093. else
  6094. ckstrncat(strTmp,"/SYSTEM32/DRIVERS/ETC",sizeof(strTmp));
  6095. }
  6096. }
  6097. ptr = strTmp;
  6098. }
  6099. #endif /* NT */
  6100. if ( ptr ) {
  6101. int len = strlen(ptr);
  6102. int i;
  6103. if (ptr != strTmp)
  6104. strcpy(strTmp,ptr);
  6105. for ( i=0;i<len;i++ ) {
  6106. if ( strTmp[i] == '\\' )
  6107. strTmp[i] = '/';
  6108. }
  6109. if ( strTmp[len-1] != '/' )
  6110. ckstrncat(strTmp,"/tpasswd",sizeof(strTmp));
  6111. else
  6112. ckstrncat(strTmp,"tpasswd",sizeof(strTmp));
  6113. tpw = t_openpwbyname(strTmp);
  6114. ckstrncat(strTmp,".conf",sizeof(strTmp));
  6115. tconf = t_openconfbyname(strTmp);
  6116. }
  6117. if ( tpw && tconf )
  6118. ts = t_serveropenfromfiles(szUserNameRequested, tpw, tconf);
  6119. else
  6120. ts = t_serveropen(szUserNameRequested);
  6121. if ( tpw ) {
  6122. t_closepw(tpw);
  6123. tpw = NULL;
  6124. }
  6125. if ( tconf ) {
  6126. t_closeconf(tconf);
  6127. tconf = NULL;
  6128. }
  6129. #else /* COMMENT */
  6130. ts = t_serveropen(szUserNameRequested);
  6131. #endif /* COMMENT */
  6132. #endif /* PRE_SRP_1_4_4 */
  6133. if( ts == NULL ) {
  6134. printf("User %s not found\r\n", szUserNameRequested);
  6135. SendSRPAuthSB(SRP_REJECT, (void *) "Password not set", -1);
  6136. return(AUTH_FAILURE);
  6137. }
  6138. pbuf = (char *)malloc(ts->n.len + ts->g.len + ts->s.len + 7);
  6139. ptr = pbuf;
  6140. srp_encode_length(ptr, ts->n.len);
  6141. ptr += 2;
  6142. memcpy(ptr, ts->n.data, ts->n.len); /* safe */
  6143. ptr += ts->n.len;
  6144. srp_encode_length(ptr, ts->g.len);
  6145. ptr += 2;
  6146. memcpy(ptr, ts->g.data, ts->g.len); /* safe */
  6147. ptr += ts->g.len;
  6148. srp_encode_length(ptr, ts->s.len);
  6149. ptr += 2;
  6150. memcpy(ptr, ts->s.data, ts->s.len); /* safe */
  6151. ptr += ts->s.len;
  6152. SendSRPAuthSB(SRP_PARAMS, pbuf, ptr - pbuf);
  6153. free(pbuf); pbuf = NULL;
  6154. B = t_servergenexp(ts);
  6155. ckstrncpy(szUserNameAuthenticated,szUserNameRequested,UIDBUFLEN);
  6156. return AUTH_SUCCESS;
  6157. case SRP_EXP:
  6158. /* Client is sending A to us, compute challenge & expected response. */
  6159. if (ts == NULL || B == NULL) {
  6160. printf("Protocol error: SRP_EXP unexpected\r\n");
  6161. SendSRPAuthSB(SRP_REJECT,
  6162. (void *) "Protocol error: unexpected EXP",
  6163. -1
  6164. );
  6165. return(AUTH_FAILURE);
  6166. }
  6167. /* Wait until now to send B, since it contains the key to "u" */
  6168. SendSRPAuthSB(SRP_CHALLENGE, B->data, B->len);
  6169. B = NULL;
  6170. #ifndef PRE_SRP_1_4_5
  6171. /*
  6172. * The original SRP AUTH implementation did not protect against
  6173. * tampering of the auth-type-pairs. Therefore, when the
  6174. * AUTH_ENCRYPT_MASK bits are zero, no extra data is inserted
  6175. * into the SRP hash computation. When AUTH_ENCRYPT_START_TLS
  6176. * is set we also insert the SSL/TLS client and server finished
  6177. * messages to ensure that there is no man in the middle attack
  6178. * underway on the SSL/TLS connection.
  6179. */
  6180. if ( (how & AUTH_ENCRYPT_MASK) != AUTH_ENCRYPT_OFF ) {
  6181. type_check[0] = AUTHTYPE_SRP;
  6182. type_check[1] = how;
  6183. #ifdef CK_SSL
  6184. if ((how & AUTH_ENCRYPT_MASK) == AUTH_ENCRYPT_START_TLS) {
  6185. ssl_get_client_finished(&type_check[2],12);
  6186. ssl_get_server_finished(&type_check[14],12);
  6187. }
  6188. #endif /* CK_SSL */
  6189. t_serveraddexdata(ts,type_check,
  6190. #ifdef CK_SSL
  6191. ((how & AUTH_ENCRYPT_MASK) == AUTH_ENCRYPT_START_TLS) ? 26 :
  6192. #endif /* CK_SSL */
  6193. 2);
  6194. }
  6195. #endif /* PRE_SRP_1_4_5 */
  6196. A.data = data;
  6197. A.len = cnt;
  6198. ptr = t_servergetkey(ts, &A);
  6199. if(ptr == NULL) {
  6200. if (1)
  6201. printf("Security alert: Trivial session key attempted\r\n");
  6202. SendSRPAuthSB(SRP_REJECT,
  6203. (void *) "Trivial session key detected",
  6204. -1
  6205. );
  6206. return(AUTH_FAILURE);
  6207. }
  6208. srp_waitresp = 1;
  6209. return AUTH_SUCCESS;
  6210. case SRP_RESPONSE:
  6211. /* Got the response; see if it's correct */
  6212. if (!srp_waitresp ||
  6213. ts == NULL
  6214. ) {
  6215. if (1)
  6216. printf("Protocol error: SRP_RESPONSE unexpected\r\n");
  6217. SendSRPAuthSB(SRP_REJECT,
  6218. (void *) "Protocol error: unexpected RESPONSE",
  6219. -1
  6220. );
  6221. return(AUTH_FAILURE);
  6222. }
  6223. srp_waitresp = 0; /* we got a response */
  6224. if (cnt < RESPONSE_LEN) {
  6225. if (1)
  6226. printf("Protocol error: malformed response\r\n");
  6227. SendSRPAuthSB(SRP_REJECT,
  6228. (void *) "Protocol error: malformed response",
  6229. -1
  6230. );
  6231. return(AUTH_FAILURE);
  6232. }
  6233. if (t_serververify(ts, data) == 0) {
  6234. SendSRPAuthSB(SRP_ACCEPT, t_serverresponse(ts), RESPONSE_LEN);
  6235. accept_complete = 1;
  6236. #ifdef CK_ENCRYPTION
  6237. #ifdef CK_SSL
  6238. if (!(ssl_active_flag || tls_active_flag))
  6239. #endif /* CK_SSL */
  6240. {
  6241. ckhexdump("SRP_RESPONSE ts",ts,sizeof(ts));
  6242. ckhexdump("SRP_RESPONSE session_key",
  6243. ts->session_key,
  6244. SESSION_KEY_LEN
  6245. );
  6246. skey.type = SK_GENERIC;
  6247. skey.length = SESSION_KEY_LEN;
  6248. skey.data = ts->session_key;
  6249. encrypt_session_key(&skey, AUTH_SERVER_TO_CLIENT);
  6250. }
  6251. #endif /* CK_ENCRYPTION */
  6252. auth_finished(AUTH_VALID);
  6253. }
  6254. else {
  6255. SendSRPAuthSB(SRP_REJECT, (void *) "Login incorrect", -1);
  6256. auth_finished(AUTH_REJECT);
  6257. return(AUTH_FAILURE);
  6258. }
  6259. return AUTH_SUCCESS;
  6260. default:
  6261. printf("Unknown SRP option %d\r\n", data[-1]);
  6262. SendSRPAuthSB(SRP_REJECT, (void *) "Unknown option received", -1);
  6263. return(AUTH_FAILURE);
  6264. }
  6265. }
  6266. #else /* PRE_SRP_1_7_3 */
  6267. static int
  6268. #ifdef CK_ANSIC
  6269. new_srp_reply(int how, unsigned char *data, int cnt)
  6270. #else
  6271. new_srp_reply(how,data,cnt) int how; unsigned char *data; int cnt;
  6272. #endif
  6273. {
  6274. data += 4; /* Point to status byte */
  6275. cnt -= 4;
  6276. if(cnt-- < 1) { /* Matches with data++ */
  6277. auth_finished(AUTH_REJECT);
  6278. return AUTH_FAILURE;
  6279. }
  6280. switch(*data++) {
  6281. case SRP_PARAMS: {
  6282. struct t_num n;
  6283. struct t_num g;
  6284. struct t_num s;
  6285. cstr * A;
  6286. if(!szUserName) {
  6287. printf("No username available\r\n");
  6288. return(auth_resend(AUTHTYPE_SRP));
  6289. }
  6290. n.len = srp_decode_length(data);
  6291. data += 2;
  6292. cnt -= 2;
  6293. if(n.len > cnt) {
  6294. printf("n too long\r\n");
  6295. return(auth_resend(AUTHTYPE_SRP));
  6296. }
  6297. n.data = data;
  6298. data += n.len;
  6299. cnt -= n.len;
  6300. g.len = srp_decode_length(data);
  6301. data += 2;
  6302. cnt -= 2;
  6303. if(g.len > cnt) {
  6304. printf("g too long\r\n");
  6305. return(auth_resend(AUTHTYPE_SRP));
  6306. }
  6307. g.data = data;
  6308. data += g.len;
  6309. cnt -= g.len;
  6310. s.len = srp_decode_length(data);
  6311. data += 2;
  6312. cnt -= 2;
  6313. if(s.len != cnt) {
  6314. printf("invalid salt\r\n");
  6315. return(auth_resend(AUTHTYPE_SRP));
  6316. }
  6317. s.data = data;
  6318. data += s.len;
  6319. cnt -= s.len;
  6320. /* If the parameters provided by the server cannot be
  6321. * validated the following function will fail.
  6322. */
  6323. c_srp = SRP_new(SRP_RFC2945_client_method());
  6324. if (c_srp == NULL ||
  6325. SRP_set_username(c_srp, szUserName) != SRP_SUCCESS ||
  6326. SRP_set_params(c_srp,n.data,n.len,g.data,g.len,s.data,s.len) !=
  6327. SRP_SUCCESS) {
  6328. printf("SRP Parameter initialization error\r\n");
  6329. return(auth_resend(AUTHTYPE_SRP));
  6330. }
  6331. A = cstr_new();
  6332. if(SRP_gen_pub(c_srp, &A) != SRP_SUCCESS) {
  6333. printf("SRP Error generating key exchange\r\n");
  6334. return(auth_resend(AUTHTYPE_SRP));
  6335. }
  6336. SendSRPAuthSB(SRP_EXP, A->data, A->length);
  6337. cstr_free(A);
  6338. if ( pwbuf[0] && pwflg ) {
  6339. printf("SRP using %d-bit modulus for '%s'\r\n",
  6340. 8 * n.len,
  6341. szUserName
  6342. );
  6343. ckstrncpy(srp_passwd,pwbuf,sizeof(srp_passwd));
  6344. #ifdef OS2
  6345. if ( pwcrypt )
  6346. ck_encrypt((char *)srp_passwd);
  6347. #endif /* OS2 */
  6348. } else {
  6349. extern char * srppwprompt;
  6350. char preface[128];
  6351. int ok;
  6352. if (srppwprompt && srppwprompt[0] &&
  6353. (strlen(srppwprompt) + strlen(szUserName) - 2) <
  6354. sizeof(preface)) {
  6355. sprintf(preface,srppwprompt,szUserName);
  6356. } else {
  6357. ckmakxmsg( preface,sizeof(preface),
  6358. "SRP using ",ckitoa(8*n.len),"-bit modulus for '",
  6359. szUserName, "'", NULL, NULL, NULL, NULL, NULL,
  6360. NULL, NULL);
  6361. }
  6362. ok = uq_txt(preface,"Password: ",2,NULL,
  6363. srp_passwd,sizeof(srp_passwd)-1,NULL,
  6364. DEFAULT_UQ_TIMEOUT);
  6365. if ( !ok )
  6366. srp_passwd[0] = '\0';
  6367. }
  6368. if(SRP_set_auth_password(c_srp, srp_passwd) != SRP_SUCCESS) {
  6369. memset(srp_passwd, 0, sizeof(srp_passwd));
  6370. printf("SRP Error setting client password\r\n");
  6371. return(auth_resend(AUTHTYPE_SRP));
  6372. }
  6373. memset(srp_passwd, 0, sizeof(srp_passwd));
  6374. return AUTH_SUCCESS;
  6375. }
  6376. case SRP_CHALLENGE: {
  6377. char type_check[26];
  6378. cstr * resp = NULL;
  6379. if(c_srp == NULL) {
  6380. printf("SRP protocol error\r\n");
  6381. return(auth_resend(AUTHTYPE_SRP));
  6382. }
  6383. /*
  6384. * The original SRP AUTH implementation did not protect against
  6385. * tampering of the auth-type-pairs. Therefore, when the
  6386. * AUTH_ENCRYPT_MASK bits are zero, no extra data is inserted
  6387. * into the SRP hash computation. When AUTH_ENCRYPT_START_TLS
  6388. * is set we also insert the SSL/TLS client and server finished
  6389. * messages to ensure that there is no man in the middle attack
  6390. * underway on the SSL/TLS connection.
  6391. */
  6392. if ((how & AUTH_ENCRYPT_MASK) != AUTH_ENCRYPT_OFF) {
  6393. type_check[0] = AUTHTYPE_SRP;
  6394. type_check[1] = how;
  6395. #ifdef CK_SSL
  6396. if ((how & AUTH_ENCRYPT_MASK) == AUTH_ENCRYPT_START_TLS) {
  6397. ssl_get_client_finished(&type_check[2],12);
  6398. ssl_get_server_finished(&type_check[14],12);
  6399. SRP_add_ex_data(c_srp, type_check, 26);
  6400. } else
  6401. #endif /* CK_SSL */
  6402. SRP_add_ex_data(c_srp, type_check, 2);
  6403. }
  6404. if(SRP_compute_key(c_srp, &c_key, data, cnt) != SRP_SUCCESS) {
  6405. printf("SRP ERROR: unable to compute client key\r\n");
  6406. return(auth_resend(AUTHTYPE_SRP));
  6407. }
  6408. resp = cstr_new();
  6409. if(SRP_respond(c_srp, &resp) != SRP_SUCCESS) {
  6410. printf("SRP ERROR: unable to compute client response\r\n");
  6411. return(auth_resend(AUTHTYPE_SRP));
  6412. }
  6413. SendSRPAuthSB(SRP_RESPONSE, resp->data, resp->length);
  6414. cstr_free(resp);
  6415. srp_waitresp = 1;
  6416. return AUTH_SUCCESS;
  6417. }
  6418. case SRP_ACCEPT: {
  6419. #ifdef CK_ENCRYPTION
  6420. Session_Key skey;
  6421. #endif /* ENCRYPTION */
  6422. if(cnt < RESPONSE_LEN || !srp_waitresp || c_srp == NULL) {
  6423. printf("SRP Protocol error\r\n");
  6424. return(auth_resend(AUTHTYPE_SRP));
  6425. }
  6426. srp_waitresp = 0;
  6427. if(SRP_verify(c_srp, data, cnt) == SRP_SUCCESS) {
  6428. printf("SRP accepts you as %s\r\n",szUserName);
  6429. #ifdef CK_SSL
  6430. if((ssl_active_flag || tls_active_flag) &&
  6431. (how & AUTH_ENCRYPT_MASK) == AUTH_ENCRYPT_START_TLS) {
  6432. printf("TLS session parameters verified by SRP\r\n");
  6433. } else
  6434. #endif /* CK_SSL */
  6435. #ifdef CK_ENCRYPTION
  6436. {
  6437. skey.type = SK_GENERIC;
  6438. skey.length = c_key->length;
  6439. skey.data = c_key->data;
  6440. encrypt_session_key(&skey, AUTH_CLIENT_TO_SERVER);
  6441. cstr_clear_free(c_key);
  6442. c_key = NULL;
  6443. }
  6444. #endif /* CK_ENCRYPTION */
  6445. accept_complete = 1;
  6446. auth_finished(AUTH_VALID);
  6447. SRP_free(c_srp);
  6448. c_srp = NULL;
  6449. return AUTH_SUCCESS;
  6450. }
  6451. else {
  6452. printf("[ Error: SRP server authentication failed ]\r\n");
  6453. return(auth_resend(AUTHTYPE_SRP));
  6454. }
  6455. }
  6456. case SRP_REJECT: {
  6457. char * str=NULL;
  6458. ckmakmsg(strTmp,sizeof(strTmp),
  6459. "SRP refuses authentication for '",szUserName,
  6460. "'\r\n",NULL);
  6461. if (cnt > 0) {
  6462. int len = strlen(strTmp);
  6463. if ( len + cnt < sizeof(strTmp) ) {
  6464. str = strTmp + strlen(strTmp);
  6465. memcpy(str,data,cnt);
  6466. str[cnt] = 0;
  6467. }
  6468. }
  6469. printf("SRP authentication failed!\r\n%s\r\n",strTmp);
  6470. auth_finished(AUTH_REJECT);
  6471. return AUTH_FAILURE;
  6472. }
  6473. default:
  6474. printf("Unknown SRP option %d\r\n", data[-1]);
  6475. return(auth_resend(AUTHTYPE_SRP));
  6476. }
  6477. /* NEVER REACHED */
  6478. }
  6479. static int
  6480. #ifdef CK_ANSIC
  6481. new_srp_is(int how, unsigned char *data, int cnt)
  6482. #else
  6483. new_srp_is(how,data,cnt) int how; unsigned char *data; int cnt;
  6484. #endif
  6485. {
  6486. char * pbuf = NULL;
  6487. char * ptr;
  6488. #ifdef CK_ENCRYPTION
  6489. Session_Key skey;
  6490. #endif
  6491. static cstr * B = NULL; /* Holder for B */
  6492. struct t_passwd * pass;
  6493. cstr * resp;
  6494. char type_check[26];
  6495. if ((cnt -= 4) < 1) {
  6496. auth_finished(AUTH_REJECT);
  6497. return AUTH_FAILURE;
  6498. }
  6499. data += 4;
  6500. cnt -= 1;
  6501. switch(*data++) {
  6502. case SRP_AUTH:
  6503. /* Send parameters back to client */
  6504. if(s_srp != NULL) {
  6505. SRP_free(s_srp);
  6506. s_srp = NULL;
  6507. }
  6508. if (B != NULL) {
  6509. cstr_free(B);
  6510. B = NULL;
  6511. }
  6512. if(!szUserNameRequested[0]) {
  6513. if (1)
  6514. printf("No username available\r\n");
  6515. SendSRPAuthSB(SRP_REJECT, (void *) "No username supplied", -1);
  6516. auth_finished(AUTH_REJECT);
  6517. return(AUTH_FAILURE);
  6518. }
  6519. #ifdef IKSD
  6520. #ifdef CK_LOGIN
  6521. if (inserver && ckxanon &&
  6522. !strcmp(szUserNameRequested,"anonymous")) {
  6523. SendSRPAuthSB(SRP_REJECT, (void *)
  6524. "anonymous login cannot be performed with Secure Remote Password",
  6525. -1);
  6526. auth_finished(AUTH_REJECT);
  6527. return(AUTH_FAILURE);
  6528. }
  6529. #endif /* CK_LOGIN */
  6530. #endif /* IKSD */
  6531. s_srp = SRP_new(SRP_RFC2945_server_method());
  6532. if(s_srp == NULL) {
  6533. printf("Error initializing SRP server\r\n");
  6534. SendSRPAuthSB(SRP_REJECT,
  6535. (void *) "SRP server init failed",
  6536. -1
  6537. );
  6538. return(AUTH_FAILURE);
  6539. }
  6540. pass = gettpnam(szUserNameRequested);
  6541. if(pass == NULL) {
  6542. printf("User %s not found\r\n", szUserNameRequested);
  6543. SendSRPAuthSB(SRP_REJECT, (void *) "Password not set", -1);
  6544. return(AUTH_FAILURE);
  6545. }
  6546. if(SRP_set_username(s_srp, szUserNameRequested) != SRP_SUCCESS ||
  6547. SRP_set_params(s_srp, pass->tc.modulus.data,
  6548. pass->tc.modulus.len,
  6549. pass->tc.generator.data,
  6550. pass->tc.generator.len,
  6551. pass->tp.salt.data,
  6552. pass->tp.salt.len) != SRP_SUCCESS ||
  6553. SRP_set_authenticator(s_srp,
  6554. pass->tp.password.data,
  6555. pass->tp.password.len) != SRP_SUCCESS) {
  6556. printf("Error initializing SRP parameters\r\n");
  6557. SendSRPAuthSB(SRP_REJECT,(void *)"SRP parameter init failed", -1);
  6558. return(AUTH_FAILURE);
  6559. }
  6560. pbuf = (char *)malloc(pass->tc.modulus.len + pass->tc.generator.len +
  6561. pass->tp.salt.len + 7);
  6562. ptr = pbuf;
  6563. srp_encode_length(ptr, pass->tc.modulus.len);
  6564. ptr += 2;
  6565. memcpy(ptr, pass->tc.modulus.data, pass->tc.modulus.len);
  6566. ptr += pass->tc.modulus.len;
  6567. srp_encode_length(ptr, pass->tc.generator.len);
  6568. ptr += 2;
  6569. memcpy(ptr, pass->tc.generator.data, pass->tc.generator.len);
  6570. ptr += pass->tc.generator.len;
  6571. srp_encode_length(ptr, pass->tp.salt.len);
  6572. ptr += 2;
  6573. memcpy(ptr, pass->tp.salt.data, pass->tp.salt.len);
  6574. ptr += pass->tp.salt.len;
  6575. SendSRPAuthSB(SRP_PARAMS, pbuf, ptr - pbuf);
  6576. free(pbuf);
  6577. pbuf = NULL;
  6578. if(SRP_gen_pub(s_srp, &B) != SRP_SUCCESS) {
  6579. printf("Error generating SRP public value\r\n");
  6580. SendSRPAuthSB(SRP_REJECT, (void *) "SRP_gen_pub failed", -1);
  6581. return(AUTH_FAILURE);
  6582. }
  6583. ckstrncpy(szUserNameAuthenticated,szUserNameRequested,UIDBUFLEN);
  6584. return AUTH_SUCCESS;
  6585. case SRP_EXP:
  6586. /* Client is sending A to us, compute challenge and expected response. */
  6587. if (s_srp == NULL || B == NULL) {
  6588. printf("Protocol error: SRP_EXP unexpected\r\n");
  6589. SendSRPAuthSB(SRP_REJECT,
  6590. (void *)"Protocol error: unexpected EXP", -1);
  6591. return(AUTH_FAILURE);
  6592. }
  6593. /* Wait until now to send B, since it contains the key to "u" */
  6594. SendSRPAuthSB(SRP_CHALLENGE, B->data, B->length);
  6595. cstr_free(B);
  6596. B = NULL;
  6597. /*
  6598. * The original SRP AUTH implementation did not protect against
  6599. * tampering of the auth-type-pairs. Therefore, when the
  6600. * AUTH_ENCRYPT_MASK bits are zero, no extra data is inserted
  6601. * into the SRP hash computation. When AUTH_ENCRYPT_START_TLS
  6602. * is set we also insert the SSL/TLS client and server finished
  6603. * messages to ensure that there is no man in the middle attack
  6604. * underway on the SSL/TLS connection.
  6605. */
  6606. if ( (how & AUTH_ENCRYPT_MASK) != AUTH_ENCRYPT_OFF ) {
  6607. type_check[0] = AUTHTYPE_SRP;
  6608. type_check[1] = how;
  6609. #ifdef CK_SSL
  6610. if ((how & AUTH_ENCRYPT_MASK) == AUTH_ENCRYPT_START_TLS) {
  6611. ssl_get_client_finished(&type_check[2],12);
  6612. ssl_get_server_finished(&type_check[14],12);
  6613. SRP_add_ex_data(s_srp, type_check, 26);
  6614. } else
  6615. #endif /* CK_SSL */
  6616. SRP_add_ex_data(s_srp, type_check, 2);
  6617. }
  6618. if(SRP_compute_key(s_srp, &s_key, data, cnt) != SRP_SUCCESS) {
  6619. printf("Security alert: Trivial session key attempted\r\n");
  6620. SendSRPAuthSB(SRP_REJECT,
  6621. (void *) "Trivial session key detected", -1);
  6622. return(AUTH_FAILURE);
  6623. }
  6624. srp_waitresp = 1;
  6625. return AUTH_SUCCESS;
  6626. case SRP_RESPONSE:
  6627. /* Got the response; see if it's correct */
  6628. if (!srp_waitresp || s_srp == NULL) {
  6629. if (1)
  6630. printf("Protocol error: SRP_RESPONSE unexpected\r\n");
  6631. SendSRPAuthSB(SRP_REJECT,
  6632. (void *) "Protocol error: unexpected RESPONSE",
  6633. -1
  6634. );
  6635. return(AUTH_FAILURE);
  6636. }
  6637. srp_waitresp = 0; /* we got a response */
  6638. if (cnt < RESPONSE_LEN) {
  6639. if (1)
  6640. printf("Protocol error: malformed response\r\n");
  6641. SendSRPAuthSB(SRP_REJECT,
  6642. (void *) "Protocol error: malformed response",
  6643. -1
  6644. );
  6645. return(AUTH_FAILURE);
  6646. }
  6647. if(SRP_verify(s_srp, data, cnt) == SRP_SUCCESS) {
  6648. resp = cstr_new();
  6649. if(SRP_respond(s_srp, &resp) != SRP_SUCCESS) {
  6650. printf("Error computing response\r\n");
  6651. SendSRPAuthSB(SRP_REJECT,
  6652. (void *) "Error computing response", -1);
  6653. return(AUTH_FAILURE);
  6654. }
  6655. SendSRPAuthSB(SRP_ACCEPT, resp->data, resp->length);
  6656. accept_complete = 1;
  6657. cstr_free(resp);
  6658. #ifdef CK_ENCRYPTION
  6659. #ifdef CK_SSL
  6660. if (!(ssl_active_flag || tls_active_flag))
  6661. #endif /* CK_SSL */
  6662. {
  6663. skey.type = SK_GENERIC;
  6664. skey.length = s_key->length;
  6665. skey.data = s_key->data;
  6666. encrypt_session_key(&skey, AUTH_SERVER_TO_CLIENT);
  6667. cstr_clear_free(s_key);
  6668. s_key = NULL;
  6669. }
  6670. #endif /* CK_ENCRYPTION */
  6671. auth_finished(AUTH_VALID);
  6672. }
  6673. else {
  6674. SendSRPAuthSB(SRP_REJECT, (void *) "Login incorrect", -1);
  6675. auth_finished(AUTH_REJECT);
  6676. return(AUTH_FAILURE);
  6677. }
  6678. return AUTH_SUCCESS;
  6679. default:
  6680. printf("Unknown SRP option %d\r\n", data[-1]);
  6681. SendSRPAuthSB(SRP_REJECT, (void *) "Unknown option received", -1);
  6682. return(AUTH_FAILURE);
  6683. }
  6684. }
  6685. #endif /* PRE_SRP_1_7_3 */
  6686. #endif /* SRP */
  6687. #ifdef KRB5
  6688. #ifdef KINIT
  6689. /*
  6690. * clients/kinit/kinit.c
  6691. *
  6692. * Copyright 1990 by the Massachusetts Institute of Technology.
  6693. * All Rights Reserved.
  6694. *
  6695. * Export of this software from the United States of America may
  6696. * require a specific license from the United States Government.
  6697. * It is the responsibility of any person or organization contemplating
  6698. * export to obtain such a license before exporting.
  6699. *
  6700. * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
  6701. * distribute this software and its documentation for any purpose and
  6702. * without fee is hereby granted, provided that the above copyright
  6703. * notice appear in all copies and that both that copyright notice and
  6704. * this permission notice appear in supporting documentation, and that
  6705. * the name of M.I.T. not be used in advertising or publicity pertaining
  6706. * to distribution of the software without specific, written prior
  6707. * permission. M.I.T. makes no representations about the suitability of
  6708. * this software for any purpose. It is provided "as is" without express
  6709. * or implied warranty.
  6710. *
  6711. *
  6712. * Initialize a credentials cache.
  6713. */
  6714. #define KRB5_DEFAULT_OPTIONS 0
  6715. #define KRB5_DEFAULT_LIFE 60*60*10 /* 10 hours */
  6716. static krb5_data tgtname = {
  6717. #ifndef HEIMDAL
  6718. 0,
  6719. #endif /* HEIMDAL */
  6720. KRB5_TGS_NAME_SIZE,
  6721. KRB5_TGS_NAME
  6722. };
  6723. /* Internal prototypes */
  6724. _PROTOTYP(static krb5_error_code krb5_validate_tgt,
  6725. (krb5_context, krb5_ccache,krb5_principal, krb5_data *));
  6726. _PROTOTYP(static krb5_error_code krb5_renew_tgt,
  6727. (krb5_context, krb5_ccache,
  6728. krb5_principal, krb5_data *));
  6729. _PROTOTYP(static krb5_error_code krb5_tgt_gen,
  6730. (krb5_context, krb5_ccache,
  6731. krb5_principal, krb5_data *, int opt));
  6732. #ifdef KRB5_HAVE_GET_INIT_CREDS
  6733. static krb5_error_code KRB5_CALLCONV
  6734. ck_krb5_prompter( krb5_context context,
  6735. void *data,
  6736. const char *name,
  6737. const char *banner,
  6738. int num_prompts,
  6739. krb5_prompt prompts[])
  6740. {
  6741. krb5_error_code errcode = 0;
  6742. int i;
  6743. #ifdef KUI
  6744. struct txtbox * tb = NULL;
  6745. #else /* KUI */
  6746. char * prompt = NULL;
  6747. #endif /* KUI */
  6748. int len = 0, blen=0, nlen=0;
  6749. debug(F110,"ck_krb5_prompter name",name,0);
  6750. debug(F110,"ck_krb5_prompter banner",banner,0);
  6751. debug(F101,"ck_krb5_prompter num_prompts","",num_prompts);
  6752. if (name)
  6753. nlen = strlen(name)+2;
  6754. if (banner)
  6755. blen = strlen(banner)+2;
  6756. #ifdef KUI
  6757. tb = (struct txtbox *) malloc(sizeof(struct txtbox) * num_prompts);
  6758. if ( tb != NULL ) {
  6759. int ok;
  6760. memset(tb,0,sizeof(struct txtbox) * num_prompts);
  6761. for ( i=0; i < num_prompts; i++ ) {
  6762. tb[i].t_buf = prompts[i].reply->data;
  6763. tb[i].t_len = prompts[i].reply->length;
  6764. tb[i].t_lbl = prompts[i].prompt;
  6765. tb[i].t_dflt = NULL;
  6766. tb[i].t_echo = (prompts[i].hidden ? 2 : 1);
  6767. }
  6768. ok = uq_mtxt((char *)banner,NULL,num_prompts,tb);
  6769. if ( ok ) {
  6770. for ( i=0; i < num_prompts; i++ )
  6771. prompts[i].reply->length = strlen(prompts[i].reply->data);
  6772. } else
  6773. errcode = -2;
  6774. }
  6775. #else /* KUI */
  6776. for (i = 0; i < num_prompts; i++) {
  6777. debug(F111,"ck_krb5_prompter prompt",prompts[i].prompt,i);
  6778. if ( prompt && len < (nlen + blen + strlen(prompts[i].prompt)+2) ) {
  6779. free(prompt);
  6780. prompt = NULL;
  6781. }
  6782. if ( !prompt )
  6783. prompt = (char *)malloc(nlen + blen + strlen(prompts[i].prompt)+2);
  6784. if ( !prompt ) {
  6785. errcode = KRB5_RC_MALLOC;
  6786. goto cleanup;
  6787. }
  6788. len = nlen + blen + strlen(prompts[i].prompt)+2;
  6789. ckmakxmsg(prompt,len,
  6790. (char *) (name?name:""),
  6791. name?"\r\n":"",
  6792. (char *) (banner?banner:""),
  6793. banner?"\r\n":"",
  6794. (char *)prompts[i].prompt,
  6795. ": ",NULL,NULL,NULL,NULL,NULL,NULL);
  6796. memset(prompts[i].reply->data, 0, prompts[i].reply->length);
  6797. if (prompts[i].hidden) {
  6798. readpass(prompt, prompts[i].reply->data,
  6799. prompts[i].reply->length);
  6800. } else {
  6801. readtext(prompt, prompts[i].reply->data,
  6802. prompts[i].reply->length);
  6803. }
  6804. prompts[i].reply->length = strlen(prompts[i].reply->data);
  6805. }
  6806. #endif /* KUI */
  6807. cleanup:
  6808. #ifdef KUI
  6809. if ( tb )
  6810. free(tb);
  6811. #else /* KUI */
  6812. if ( prompt )
  6813. free(prompt);
  6814. #endif /* KUI */
  6815. if (errcode) {
  6816. for (i = 0; i < num_prompts; i++) {
  6817. memset(prompts[i].reply->data, 0, prompts[i].reply->length);
  6818. }
  6819. }
  6820. return errcode;
  6821. }
  6822. /*
  6823. * I'm not really sure what to do with this. The NRL DLLs use a
  6824. * different interface for the krb5_prompter callback. It has
  6825. * one less parameter. This is going to be ugly.
  6826. */
  6827. static krb5_error_code KRB5_CALLCONV
  6828. ck_NRL_krb5_prompter( krb5_context context,
  6829. const char *name,
  6830. const char *banner,
  6831. int num_prompts,
  6832. krb5_prompt prompts[])
  6833. {
  6834. return(ck_krb5_prompter(context,NULL,name,banner,num_prompts,prompts));
  6835. }
  6836. #endif /* KRB5_HAVE_GET_INIT_CREDS */
  6837. #ifdef KRB524_CONV
  6838. long
  6839. try_convert524(krb5_context ctx, krb5_principal me, krb5_ccache cc)
  6840. {
  6841. char * progname = "convert524";
  6842. krb5_error_code code = 0;
  6843. int icode = 0;
  6844. krb5_principal kpcserver = 0;
  6845. krb5_creds *v5creds = 0;
  6846. krb5_creds increds;
  6847. #ifdef OS2
  6848. LEASH_CREDENTIALS v4creds;
  6849. #else /* OS2 */
  6850. CREDENTIALS v4creds;
  6851. #endif /* OS2 */
  6852. memset((char *) &increds, 0, sizeof(increds));
  6853. /*
  6854. From this point on, we can goto cleanup because increds is
  6855. initialized.
  6856. */
  6857. if ((code = krb5_build_principal(ctx,
  6858. &kpcserver,
  6859. krb5_princ_realm(ctx, me)->length,
  6860. krb5_princ_realm(ctx, me)->data,
  6861. "krbtgt",
  6862. krb5_princ_realm(ctx, me)->data,
  6863. NULL))) {
  6864. com_err(progname, code,
  6865. "while creating service principal name");
  6866. goto cleanup;
  6867. }
  6868. memset((char*) &increds, 0, sizeof(increds));
  6869. increds.client = me;
  6870. increds.server = kpcserver;
  6871. /* Prevent duplicate free calls. */
  6872. kpcserver = 0;
  6873. increds.times.endtime = 0;
  6874. increds.keyblock.enctype = ENCTYPE_DES_CBC_CRC;
  6875. if ((code = krb5_get_credentials(ctx, 0,
  6876. cc,
  6877. &increds,
  6878. &v5creds))) {
  6879. com_err(progname, code,
  6880. "getting V5 credentials");
  6881. goto cleanup;
  6882. }
  6883. if ((icode = krb524_convert_creds_kdc(ctx,
  6884. v5creds,
  6885. &v4creds))) {
  6886. com_err(progname, icode,
  6887. "converting to V4 credentials");
  6888. goto cleanup;
  6889. }
  6890. /* this is stolen from the v4 kinit */
  6891. /* initialize ticket cache */
  6892. if ((icode = krb_in_tkt(v4creds.pname, v4creds.pinst, v4creds.realm)
  6893. != KSUCCESS)) {
  6894. com_err(progname, icode,
  6895. "trying to create the V4 ticket file");
  6896. goto cleanup;
  6897. }
  6898. /* stash ticket, session key, etc. for future use */
  6899. if ((icode = krb_save_credentials(v4creds.service,
  6900. v4creds.instance,
  6901. v4creds.realm,
  6902. v4creds.session,
  6903. v4creds.lifetime,
  6904. v4creds.kvno,
  6905. &(v4creds.ticket_st),
  6906. v4creds.issue_date))) {
  6907. com_err(progname, icode,
  6908. "trying to save the V4 ticket");
  6909. goto cleanup;
  6910. }
  6911. cleanup:
  6912. memset(&v4creds, 0, sizeof(v4creds));
  6913. if (v5creds)
  6914. krb5_free_creds(ctx, v5creds);
  6915. increds.client = 0;
  6916. krb5_free_cred_contents(ctx, &increds);
  6917. if (kpcserver)
  6918. krb5_free_principal(ctx, kpcserver);
  6919. return !(code || icode);
  6920. }
  6921. #endif /* KRB524_CONV */
  6922. #define NO_KEYTAB
  6923. int
  6924. #ifdef CK_ANSIC
  6925. ck_krb5_initTGT( struct krb_op_data * op, struct krb5_init_data * init,
  6926. struct krb4_init_data * k4_init)
  6927. #else
  6928. ck_krb5_initTGT(op,init,k4_init)
  6929. krb_op_data * op; struct krb5_init_data * init;
  6930. struct krb4_init_data * k4_init;
  6931. #endif /* CK_ANSIC*/
  6932. {
  6933. krb5_context kcontext;
  6934. krb5_ccache ccache = NULL;
  6935. krb5_deltat lifetime = KRB5_DEFAULT_LIFE; /* -l option */
  6936. krb5_timestamp starttime = 0;
  6937. krb5_deltat rlife = 0;
  6938. int options = KRB5_DEFAULT_OPTIONS;
  6939. int option;
  6940. int errflg = 0;
  6941. krb5_error_code code;
  6942. krb5_principal me=NULL;
  6943. krb5_principal server=NULL;
  6944. krb5_creds my_creds;
  6945. krb5_timestamp now;
  6946. #ifndef HEIMDAL
  6947. krb5_address **addrs = (krb5_address **)0;
  6948. #endif /* HEIMDAL */
  6949. int addr_count=0;
  6950. int i,j;
  6951. #ifndef NO_KEYTAB
  6952. int use_keytab = 0; /* -k option */
  6953. krb5_keytab keytab = NULL;
  6954. #endif /* NO_KEYTAB */
  6955. struct passwd *pw = 0;
  6956. int pwsize;
  6957. char *client_name=NULL, principal[256]="", realm[256]="", numstr[40]="";
  6958. char *password=NULL, passwd[80]="";
  6959. #ifdef KRB5_HAVE_GET_INIT_CREDS
  6960. krb5_get_init_creds_opt opts;
  6961. #endif
  6962. char * name;
  6963. int len;
  6964. if ( !ck_krb5_is_installed() )
  6965. return(-1);
  6966. #ifdef COMMENT
  6967. printf("Kerberos V initialization\r\n");
  6968. #endif /* COMMENT */
  6969. code = krb5_init_context(&kcontext);
  6970. if (code) {
  6971. com_err("krb5_kinit",code,"while init_context");
  6972. krb5_errno = code;
  6973. makestr(&krb5_errmsg,error_message(krb5_errno));
  6974. return(-1);
  6975. }
  6976. debug(F110,"krb5_init","krb5_init_context",0);
  6977. if ((code = krb5_timeofday(kcontext, &now))) {
  6978. com_err("krb5_kinit",code,"while getting time of day");
  6979. goto exit_k5_init;
  6980. }
  6981. #ifdef KRB5_HAVE_GET_INIT_CREDS
  6982. memset(&opts, 0, sizeof(opts));
  6983. krb5_get_init_creds_opt_init(&opts);
  6984. debug(F110,"krb5_init","krb5_get_init_creds_opt_init",0);
  6985. #endif
  6986. if ( init->renewable ) {
  6987. options |= KDC_OPT_RENEWABLE;
  6988. ckmakmsg(numstr,sizeof(numstr),ckitoa(init->renewable),"m",NULL,NULL);
  6989. #ifdef HEIMDAL
  6990. code = -1;
  6991. #else /* HEIMDAL */
  6992. code = krb5_string_to_deltat(numstr, &rlife);
  6993. #endif /* HEIMDAL */
  6994. if (code != 0 || rlife == 0) {
  6995. printf("Bad renewable time value %s\r\n", numstr);
  6996. errflg++;
  6997. }
  6998. #ifdef KRB5_HAVE_GET_INIT_CREDS
  6999. krb5_get_init_creds_opt_set_renew_life(&opts, rlife);
  7000. #endif
  7001. }
  7002. if ( init->renew ) {
  7003. /* renew the ticket */
  7004. options |= KDC_OPT_RENEW;
  7005. }
  7006. if ( init->validate ) {
  7007. /* validate the ticket */
  7008. options |= KDC_OPT_VALIDATE;
  7009. }
  7010. if ( init->proxiable ) {
  7011. options |= KDC_OPT_PROXIABLE;
  7012. #ifdef KRB5_HAVE_GET_INIT_CREDS
  7013. krb5_get_init_creds_opt_set_proxiable(&opts, 1);
  7014. #endif
  7015. }
  7016. if ( init->forwardable ) {
  7017. options |= KDC_OPT_FORWARDABLE;
  7018. #ifdef KRB5_HAVE_GET_INIT_CREDS
  7019. krb5_get_init_creds_opt_set_forwardable(&opts, 1);
  7020. #endif
  7021. }
  7022. #ifndef NO_KEYTAB
  7023. if ( ) {
  7024. use_keytab = 1;
  7025. }
  7026. if ( ) {
  7027. if (keytab == NULL && keytab_name != NULL) {
  7028. code = krb5_kt_resolve(kcontext, keytab_name, &keytab);
  7029. if (code != 0) {
  7030. debug(F111,"krb5_init resolving keytab",
  7031. keytab_name,code);
  7032. errflg++;
  7033. }
  7034. }
  7035. }
  7036. #endif /* NO_KEYTAB */
  7037. if ( init->lifetime ) {
  7038. ckmakmsg(numstr,sizeof(numstr),ckitoa(init->lifetime),"m",NULL,NULL);
  7039. #ifdef HEIMDAL
  7040. code = -1;
  7041. #else /* HEIMDAL */
  7042. code = krb5_string_to_deltat(numstr, &lifetime);
  7043. #endif /* HEIMDAL */
  7044. if (code != 0 || lifetime == 0) {
  7045. printf("Bad lifetime value %s\r\n", numstr);
  7046. errflg++;
  7047. }
  7048. #ifdef KRB5_HAVE_GET_INIT_CREDS
  7049. krb5_get_init_creds_opt_set_tkt_life(&opts, lifetime);
  7050. #endif
  7051. }
  7052. if ( init->postdate ) {
  7053. /* Convert cmdate() to a time_t value */
  7054. struct tm * time_tm;
  7055. struct tm * cmdate2tm(char *,int);
  7056. time_tm = cmdate2tm(init->postdate,0);
  7057. if ( time_tm )
  7058. starttime = (krb5_timestamp) mktime(time_tm);
  7059. if (code != 0 || starttime == 0 || starttime == -1) {
  7060. krb5_deltat ktmp;
  7061. #ifdef HEIMDAL
  7062. code = -1;
  7063. #else /* HEIMDAL */
  7064. code = krb5_string_to_deltat(init->postdate, &ktmp);
  7065. #endif /* HEIMDAL */
  7066. if (code == 0 && ktmp != 0) {
  7067. starttime = now + ktmp;
  7068. options |= KDC_OPT_POSTDATED;
  7069. } else {
  7070. printf("Bad postdate start time value %s\r\n",
  7071. init->postdate);
  7072. errflg++;
  7073. }
  7074. } else {
  7075. options |= KDC_OPT_POSTDATED;
  7076. }
  7077. }
  7078. debug(F110,"krb5_init searching for ccache",op->cache,0);
  7079. code = k5_get_ccache(kcontext,&ccache,op->cache);
  7080. if (code != 0) {
  7081. com_err("krb5_kinit",code,"while getting default ccache");
  7082. goto exit_k5_init;
  7083. }
  7084. /* This is our realm unless it is changed */
  7085. ckstrncpy(realm,init->realm ? init->realm : krb5_d_realm, 256);
  7086. #ifdef BETATEST
  7087. /* This code is going to take the realm and attempt to correct */
  7088. /* the case. */
  7089. {
  7090. profile_t profile;
  7091. code = krb5_get_profile(kcontext, &profile);
  7092. if ( !code ) {
  7093. const char *names[4];
  7094. char ** realms;
  7095. int found = 0;
  7096. names[0] = "realms";
  7097. names[1] = NULL;
  7098. code = profile_get_subsection_names(profile,names,&realms);
  7099. if ( code == 0 ) {
  7100. int i=0;
  7101. while ( realms[i] ) {
  7102. if (ckstrcmp(realm,realms[i],-1,0) == 0) {
  7103. strcpy(realm,realms[i]);
  7104. found = 1;
  7105. break;
  7106. }
  7107. i++;
  7108. }
  7109. }
  7110. #ifdef CK_DNS_SRV
  7111. if ( !found ) {
  7112. char * dns_realm = NULL;
  7113. /* We did not find the realm in the profile so let's try DNS */
  7114. locate_txt_rr("_kerberos",realm,&dns_realm);
  7115. if ( dns_realm &&
  7116. ckstrcmp(realm,dns_realm,-1,0) == 0 &&
  7117. ckstrcmp(realm,dns_realm,-1,1) != 0
  7118. ) {
  7119. ckstrncpy(realm,dns_realm,256);
  7120. free(dns_realm);
  7121. }
  7122. }
  7123. #endif /* CK_DNS_SRV */
  7124. }
  7125. if (init->realm &&
  7126. ckstrcmp(realm,init->realm,-1,0) == 0 &&
  7127. ckstrcmp(realm,init->realm,-1,1) != 0)
  7128. strcpy(init->realm,realm);
  7129. if (ckstrcmp(realm,krb5_d_realm,-1,0) == 0 &&
  7130. ckstrcmp(realm,krb5_d_realm,-1,1) != 0)
  7131. strcpy(krb5_d_realm,realm);
  7132. }
  7133. #endif /* BETATEST */
  7134. if (init->principal == NULL) { /* No principal name specified */
  7135. #ifndef NO_KEYTAB
  7136. if (use_keytab) {
  7137. /* Use the default host/service name */
  7138. code = krb5_sname_to_principal(kcontext, NULL, NULL,
  7139. KRB5_NT_SRV_HST, &me);
  7140. if (code == 0 &&
  7141. krb5_princ_realm(kcontext, me)->length < sizeof(realm))
  7142. {
  7143. /* Save the realm */
  7144. memcpy(realm,krb5_princ_realm(kcontext, me)->data,
  7145. krb5_princ_realm(kcontext, me)->length); /* safe */
  7146. realm[krb5_princ_realm(kcontext, me)->length]='\0';
  7147. } else {
  7148. com_err("krb5_kinit",
  7149. code,
  7150. "when creating default server principal name");
  7151. goto exit_k5_init;
  7152. }
  7153. } else
  7154. #endif /* NO_KEYTAB */
  7155. {
  7156. int len;
  7157. char * name;
  7158. /* Get default principal from cache if one exists */
  7159. code = krb5_cc_get_principal(kcontext, ccache, &me);
  7160. #ifdef HEIMDAL
  7161. name = me->realm;
  7162. len = strlen(name);
  7163. #else /* HEIMDAL */
  7164. len = krb5_princ_realm(kcontext, me)->length;
  7165. name = krb5_princ_realm(kcontext, me)->data;
  7166. #endif /* HEIMDAL */
  7167. if (code == 0 && len < sizeof(realm))
  7168. {
  7169. /* Save the realm */
  7170. memcpy(realm,name,len); /* safe */
  7171. realm[len]='\0';
  7172. } else {
  7173. #ifdef HAVE_PWD_H
  7174. /* Else search passwd file for client */
  7175. pw = getpwuid((int) getuid());
  7176. if (pw) {
  7177. char princ_realm[256];
  7178. if ( (strlen(pw->pw_name) + strlen(realm) + 1) > 255 )
  7179. goto exit_k5_init;
  7180. ckstrncpy(principal,pw->pw_name,256);
  7181. ckstrncpy(princ_realm,pw->pw_name,256);
  7182. ckstrncat(princ_realm,"@",256);
  7183. ckstrncat(princ_realm,realm,256);
  7184. if ((code = krb5_parse_name(kcontext,princ_realm,&me))) {
  7185. krb5_errno = code;
  7186. com_err("krb5_kinit",code,"when parsing name",
  7187. princ_realm);
  7188. goto exit_k5_init;
  7189. }
  7190. } else {
  7191. printf(
  7192. "Unable to identify user from password file\r\n");
  7193. goto exit_k5_init;
  7194. }
  7195. #else /* HAVE_PWD_H */
  7196. printf("Unable to identify user\r\n");
  7197. goto exit_k5_init;
  7198. #endif /* HAVE_PWD_H */
  7199. }
  7200. }
  7201. #ifdef HEIMDAL
  7202. len = me->name.name_string.len;
  7203. name = *me->name.name_string.val;
  7204. #else /* HEIMDAL */
  7205. len = krb5_princ_name(kcontext, me)->length;
  7206. name = krb5_princ_name(kcontext, me)->data;
  7207. #endif /* HEIMDAL */
  7208. if ( len < sizeof(principal) ) {
  7209. memcpy(principal,name,len); /* safe */
  7210. principal[len]='\0';
  7211. }
  7212. } /* Use specified name */
  7213. else {
  7214. char princ_realm[256];
  7215. if ( (strlen(init->principal) +
  7216. (init->instance ? strlen(init->instance)+1 : 0) +
  7217. strlen(realm)
  7218. + 2) > 255 )
  7219. goto exit_k5_init;
  7220. ckstrncpy(principal,init->principal,256);
  7221. ckstrncpy(princ_realm,init->principal,256);
  7222. if (init->instance) {
  7223. ckstrncat(princ_realm,"/",256);
  7224. ckstrncat(princ_realm,init->instance,256);
  7225. }
  7226. if (realm[0]) {
  7227. ckstrncat(princ_realm,"@",256);
  7228. ckstrncat(princ_realm,realm,256);
  7229. }
  7230. if ((code = krb5_parse_name (kcontext, princ_realm, &me))) {
  7231. com_err("krb5_kinit",code,"when parsing name",princ_realm);
  7232. goto exit_k5_init;
  7233. }
  7234. }
  7235. if ((code = krb5_unparse_name(kcontext, me, &client_name))) {
  7236. com_err("krb5_kinit",code,"when unparsing name");
  7237. goto exit_k5_init;
  7238. }
  7239. debug(F110,"krb5_init client_name",client_name,0);
  7240. memset((char *)&my_creds, 0, sizeof(my_creds));
  7241. my_creds.client = me;
  7242. if (init->service == NULL) {
  7243. if ((code =
  7244. krb5_build_principal_ext(kcontext,
  7245. &server,
  7246. strlen(realm),realm,
  7247. tgtname.length, tgtname.data,
  7248. strlen(realm),realm,
  7249. 0))) {
  7250. com_err("krb5_kinit",code,"while building server name");
  7251. goto exit_k5_init;
  7252. }
  7253. } else {
  7254. if (code = krb5_parse_name(kcontext, init->service, &server)) {
  7255. com_err("krb5_kinit",code,"while parsing service name",
  7256. init->service);
  7257. goto exit_k5_init;
  7258. }
  7259. }
  7260. my_creds.server = server;
  7261. if (options & KDC_OPT_POSTDATED) {
  7262. my_creds.times.starttime = starttime;
  7263. my_creds.times.endtime = starttime + lifetime;
  7264. } else {
  7265. my_creds.times.starttime = 0; /* start timer when request
  7266. gets to KDC */
  7267. my_creds.times.endtime = now + lifetime;
  7268. }
  7269. if (options & KDC_OPT_RENEWABLE) {
  7270. my_creds.times.renew_till = now + rlife;
  7271. } else
  7272. my_creds.times.renew_till = 0;
  7273. if (options & KDC_OPT_VALIDATE) {
  7274. krb5_data outbuf;
  7275. #ifdef KRB5_HAVE_GET_INIT_CREDS
  7276. code = krb5_get_validated_creds(kcontext,
  7277. &my_creds, me, ccache, init->service);
  7278. if ( code == -1 )
  7279. #endif
  7280. {
  7281. #ifdef HEIMDAL
  7282. printf("?validate not implemented\r\n");
  7283. code = -1;
  7284. goto exit_k5_init;
  7285. #else /* HEIMDAL */
  7286. code = krb5_validate_tgt(kcontext, ccache, server, &outbuf);
  7287. #endif /* HEIMDAL */
  7288. }
  7289. if (code) {
  7290. com_err("krb5_kinit",code,"validating tgt");
  7291. goto exit_k5_init;
  7292. }
  7293. /* should be done... */
  7294. goto exit_k5_init;
  7295. }
  7296. if (options & KDC_OPT_RENEW) {
  7297. krb5_data outbuf;
  7298. #ifdef KRB5_HAVE_GET_INIT_CREDS
  7299. code = krb5_get_renewed_creds(kcontext,
  7300. &my_creds, me, ccache, init->service);
  7301. if ( code == -1 )
  7302. #endif
  7303. {
  7304. #ifdef HEIMDAL
  7305. printf("?renew not implemented\r\n");
  7306. code = -1;
  7307. goto exit_k5_init;
  7308. #else /* HEIMDAL */
  7309. code = krb5_renew_tgt(kcontext, ccache, server, &outbuf);
  7310. #endif /* HEIMDAL */
  7311. }
  7312. if (code) {
  7313. com_err("krb5_kinit",code,"while renewing tgt");
  7314. goto exit_k5_init;
  7315. }
  7316. /* should be done... */
  7317. goto store_cred;
  7318. }
  7319. #ifndef HEIMDAL
  7320. if ( init->addrs && !init->no_addresses ) {
  7321. /* construct an array of krb5_address structs to pass to get_in_tkt */
  7322. /* include both the local ip addresses as well as any other that */
  7323. /* are specified. */
  7324. unsigned long ipaddr;
  7325. for ( addr_count=0;addr_count<KRB5_NUM_OF_ADDRS;addr_count++ )
  7326. if ( init->addrs[addr_count] == NULL )
  7327. break;
  7328. if (addr_count > 0) {
  7329. krb5_address ** local_addrs=NULL;
  7330. krb5_os_localaddr(kcontext, &local_addrs);
  7331. i = 0;
  7332. while ( local_addrs[i] )
  7333. i++;
  7334. addr_count += i;
  7335. addrs = (krb5_address **)
  7336. malloc((addr_count+1) * sizeof(krb5_address *));
  7337. if ( !addrs ) {
  7338. krb5_free_addresses(kcontext, local_addrs);
  7339. goto exit_k5_init;
  7340. }
  7341. memset(addrs, 0, sizeof(krb5_address *) * (addr_count+1));
  7342. i = 0;
  7343. while ( local_addrs[i] ) {
  7344. addrs[i] = (krb5_address *)malloc(sizeof(krb5_address));
  7345. if (addrs[i] == NULL) {
  7346. krb5_free_addresses(kcontext, local_addrs);
  7347. goto exit_k5_init;
  7348. }
  7349. addrs[i]->magic = local_addrs[i]->magic;
  7350. addrs[i]->addrtype = local_addrs[i]->addrtype;
  7351. addrs[i]->length = local_addrs[i]->length;
  7352. addrs[i]->contents = (unsigned char *)malloc(addrs[i]->length);
  7353. if (!addrs[i]->contents) {
  7354. krb5_free_addresses(kcontext, local_addrs);
  7355. goto exit_k5_init;
  7356. }
  7357. memcpy(addrs[i]->contents,local_addrs[i]->contents,
  7358. local_addrs[i]->length); /* safe */
  7359. i++;
  7360. }
  7361. krb5_free_addresses(kcontext, local_addrs);
  7362. for ( j=0;i<addr_count;i++,j++ ) {
  7363. addrs[i] = (krb5_address *)malloc(sizeof(krb5_address));
  7364. if (addrs[i] == NULL)
  7365. goto exit_k5_init;
  7366. addrs[i]->magic = KV5M_ADDRESS;
  7367. addrs[i]->addrtype = AF_INET;
  7368. addrs[i]->length = 4;
  7369. addrs[i]->contents = (unsigned char *)malloc(addrs[i]->length);
  7370. if (!addrs[i]->contents)
  7371. goto exit_k5_init;
  7372. ipaddr = inet_addr(init->addrs[j]);
  7373. memcpy(addrs[i]->contents,&ipaddr,4); /* safe */
  7374. }
  7375. #ifdef KRB5_HAVE_GET_INIT_CREDS
  7376. krb5_get_init_creds_opt_set_address_list(&opts,addrs);
  7377. #endif
  7378. }
  7379. }
  7380. #endif /* !HEIMDAL */
  7381. #ifdef KRB5_HAVE_GET_INIT_CREDS
  7382. if ( init->no_addresses )
  7383. krb5_get_init_creds_opt_set_address_list(&opts,NULL);
  7384. #endif
  7385. #ifndef NO_KEYTAB
  7386. if (!use_keytab)
  7387. #endif
  7388. {
  7389. if ( init->password ) {
  7390. pwsize = strlen(init->password);
  7391. if ( pwsize )
  7392. password = init->password;
  7393. } else if (init->getk4 && k4_init) {
  7394. /* When we are requesting that K4 tickets be automatically */
  7395. /* acquired when K5 tickets are acquired, we must get the */
  7396. /* password up front. */
  7397. char prmpt[256];
  7398. extern char * k5prprompt;
  7399. extern char * k5pwprompt;
  7400. int ok = 0;
  7401. if ( k5pwprompt && k5pwprompt[0] &&
  7402. (strlen(k5pwprompt) + strlen(principal) +
  7403. strlen(realm) - 4) < sizeof(prmpt)) {
  7404. sprintf(prmpt,k5pwprompt,principal,realm);
  7405. } else
  7406. ckmakxmsg(prmpt,sizeof(prmpt),
  7407. k5pwprompt && k5pwprompt[0] ? k5pwprompt :
  7408. "Kerberos 5 Password for ",
  7409. principal,"@",realm,": ",
  7410. NULL,NULL,NULL,NULL,NULL,NULL,NULL
  7411. );
  7412. ok = uq_txt(NULL,prmpt,2,NULL,passwd,80,NULL,DEFAULT_UQ_TIMEOUT);
  7413. if ( ok )
  7414. password = passwd;
  7415. if ( k4_init->password == NULL )
  7416. makestr(&k4_init->password,passwd);
  7417. }
  7418. #ifdef KRB5_HAVE_GET_INIT_CREDS
  7419. debug(F100,"krb5_init calling krb5_get_init_creds_password()","",0);
  7420. #ifdef OS2
  7421. if ( is_NRL_KRB5() )
  7422. code = krb5_get_init_creds_password(kcontext, &my_creds, me,
  7423. password,
  7424. (void *)ck_NRL_krb5_prompter,
  7425. NULL,
  7426. starttime, init->service,
  7427. &opts);
  7428. else
  7429. #endif /* OS2 */
  7430. code = krb5_get_init_creds_password(kcontext, &my_creds, me,
  7431. password,
  7432. ck_krb5_prompter,
  7433. NULL,
  7434. starttime, init->service,
  7435. &opts);
  7436. debug(F111,"krb5_init","krb5_get_init_creds_password()",code);
  7437. if ( code == -1 )
  7438. {
  7439. if (!password) {
  7440. char prmpt[256];
  7441. int ok;
  7442. ckmakmsg(prmpt,sizeof(prmpt),"Kerberos 5 Password for ",
  7443. client_name,": ",NULL);
  7444. ok = uq_txt(NULL,prmpt,2,NULL,passwd,80,NULL,
  7445. DEFAULT_UQ_TIMEOUT);
  7446. if ( ok )
  7447. password = passwd;
  7448. else {
  7449. code = -2;
  7450. goto exit_k5_init;
  7451. }
  7452. }
  7453. if ( !password )
  7454. password = "";
  7455. code = krb5_get_in_tkt_with_password(kcontext, options,
  7456. #ifdef HEIMDAL
  7457. NULL,
  7458. #else /* HEIMDAL */
  7459. init->no_addresses ? NULL :addrs,
  7460. #endif /* HEIMDAL */
  7461. NULL, NULL,
  7462. password,
  7463. NULL, &my_creds, NULL);
  7464. if ( code )
  7465. debug(F111,"krb5_init","krb5_get_in_tkt_with_password()",code);
  7466. }
  7467. #else /* KRB5_HAVE_GET_INIT_CREDS */
  7468. if (!password) {
  7469. char prmpt[256];
  7470. int ok;
  7471. ckmakmsg(prmpt,sizeof(prmpt),"Kerberos 5 Password for ",
  7472. client_name,": ",NULL);
  7473. ok = uq_txt(NULL,prmpt,2,NULL,passwd,80,NULL,DEFAULT_UQ_TIMEOUT);
  7474. if ( ok )
  7475. password = passwd;
  7476. else {
  7477. code = -2;
  7478. goto exit_k5_init;
  7479. }
  7480. }
  7481. if ( !password )
  7482. password = "";
  7483. code = krb5_get_in_tkt_with_password(kcontext, options,
  7484. #ifdef HEIMDAL
  7485. NULL,
  7486. #else /* HEIMDAL */
  7487. init->no_addresses ? NULL :addrs,
  7488. #endif /* HEIMDAL */
  7489. NULL, NULL,
  7490. password,
  7491. NULL, &my_creds, NULL);
  7492. if ( code )
  7493. debug(F111,"krb5_init","krb5_get_in_tkt_with_password()",code);
  7494. #endif /* KRB5_HAVE_GET_INIT_CREDS */
  7495. if ( init->password && pwsize > 0 )
  7496. memset(init->password, 0, pwsize);
  7497. memset(passwd,0,80);
  7498. }
  7499. #ifndef NO_KEYTAB
  7500. else {
  7501. #ifdef KRB5_HAVE_GET_INIT_CREDS
  7502. code = krb5_get_init_creds_keytab(kcontext, &my_creds, me, keytab,
  7503. starttime, init->service,
  7504. &opts);
  7505. #ifdef OS2
  7506. if ( code == -1)
  7507. code = krb5_get_in_tkt_with_keytab(kcontext, options,
  7508. init->no_addresses ? NULL :addrs,
  7509. NULL, NULL, keytab, NULL,
  7510. &my_creds, 0);
  7511. #endif /* OS2 */
  7512. #else /* KRB5_HAVE_GET_INIT_CREDS */
  7513. code = krb5_get_in_tkt_with_keytab(kcontext, options,
  7514. #ifdef HEIMDAL
  7515. NULL,
  7516. #else /* HEIMDAL */
  7517. init->no_addresses ? NULL :addrs,
  7518. #endif /* HEIMDAL */
  7519. NULL, NULL, keytab, NULL,
  7520. &my_creds, 0);
  7521. #endif /* KRB5_HAVE_GET_INIT_CREDS */
  7522. }
  7523. #endif
  7524. if (code) {
  7525. switch (code) {
  7526. case KRB5KRB_AP_ERR_BAD_INTEGRITY:
  7527. printf("Password incorrect\r\n");
  7528. goto exit_k5_init;
  7529. case KRB5KRB_AP_ERR_V4_REPLY:
  7530. if (init->getk4 && k4_init) {
  7531. printf("Kerberos 5 Tickets not support by server. ");
  7532. printf("A version 4 Ticket will be requested.\r\n");
  7533. }
  7534. goto exit_k5_init;
  7535. default:
  7536. goto exit_k5_init;
  7537. }
  7538. }
  7539. store_cred:
  7540. debug(F100,"krb5_init calling krb5_cc_initialize()","",0);
  7541. code = krb5_cc_initialize (kcontext, ccache, me);
  7542. if ( code == KRB5_CC_BADNAME ) {
  7543. /* This is a really ugly hack that should not have to be here.
  7544. * krb5_cc_initialize should not fail with an error if the
  7545. * cache already exists. The reason the problem is occuring
  7546. * is that the krb5 library is no longer calling cc_destroy()
  7547. * when cc_initialize() is called and the CCAPI implementation
  7548. * on Windows has not yet been corrected to handle it. To
  7549. * ensure that K95 will continue to work with both we will call
  7550. * cc_destroy() if the cc_initialize() call fails with a BADNAME
  7551. * error. If the cc_destroy() is successful, we will try again.
  7552. */
  7553. debug(F100,"krb5_init calling krb5_cc_destroy()","",0);
  7554. code = krb5_cc_destroy (kcontext, ccache);
  7555. if ( !code ) {
  7556. debug(F100,"krb5_init calling k5_get_ccache()","",0);
  7557. code = k5_get_ccache(kcontext,&ccache,op->cache);
  7558. debug(F100,"krb5_init calling krb5_cc_initialize()","",0);
  7559. code = krb5_cc_initialize (kcontext, ccache, me);
  7560. } else
  7561. code = KRB5_CC_BADNAME;
  7562. }
  7563. if (code) {
  7564. com_err("krb5_kinit",code,"when initializing cache",op->cache);
  7565. goto exit_k5_init;
  7566. }
  7567. debug(F100,"krb5_init calling krb5_cc_store_cred()","",0);
  7568. code = krb5_cc_store_cred(kcontext, ccache, &my_creds);
  7569. if (code) {
  7570. com_err("krb5_kinit",code,"while storing credentials");
  7571. goto exit_k5_init;
  7572. }
  7573. if ( init->getk4 &&
  7574. #ifdef KRB524_CONV
  7575. !try_convert524(kcontext,me,ccache) &&
  7576. #endif /* KRB524_CONV */
  7577. k4_init ) {
  7578. int k4rc = ck_krb4_initTGT(op,k4_init);
  7579. if (k4rc < 0)
  7580. code = -3;
  7581. }
  7582. exit_k5_init:
  7583. debug(F100,"krb5_init exit_k5_init","",0);
  7584. #ifndef HEIMDAL
  7585. /* Free krb5_address structures if we created them */
  7586. if ( addrs ) {
  7587. for ( i=0;i<addr_count;i++ ) {
  7588. if ( addrs[i] ) {
  7589. if ( addrs[i]->contents )
  7590. free(addrs[i]->contents);
  7591. free(addrs[i]);
  7592. }
  7593. }
  7594. }
  7595. #endif /* HEIMDAL */
  7596. krb5_errno = code;
  7597. makestr(&krb5_errmsg,krb5_errno ? error_message(krb5_errno) : "OK");
  7598. if (client_name)
  7599. krb5_free_unparsed_name(kcontext, client_name);
  7600. /* my_creds is pointing at server */
  7601. debug(F100,"krb5_init calling krb5_free_principal()","",0);
  7602. krb5_free_principal(kcontext, server);
  7603. debug(F100,"krb5_init calling krb5_cc_close()","",0);
  7604. krb5_cc_close(kcontext,ccache);
  7605. debug(F100,"krb5_init calling krb5_free_context()","",0);
  7606. krb5_free_context(kcontext);
  7607. if (code != -2)
  7608. printf("Result from realm %s: %s\r\n",realm,
  7609. code==-3?"Unable to retrieve Kerberos IV credentials":
  7610. code?error_message(code):"OK");
  7611. return(code?-1:0);
  7612. }
  7613. #ifndef HEIMDAL
  7614. #define VALIDATE 0
  7615. #define RENEW 1
  7616. /* stripped down version of krb5_mk_req */
  7617. static krb5_error_code
  7618. #ifdef CK_ANSIC
  7619. krb5_validate_tgt( krb5_context context,
  7620. krb5_ccache ccache,
  7621. krb5_principal server, /* tgtname */
  7622. krb5_data *outbuf )
  7623. #else
  7624. krb5_validate_tgt(context, ccache, server, outbuf)
  7625. krb5_context context;
  7626. krb5_ccache ccache;
  7627. krb5_principal server; /* tgtname */
  7628. krb5_data *outbuf;
  7629. #endif
  7630. {
  7631. return krb5_tgt_gen(context, ccache, server, outbuf, VALIDATE);
  7632. }
  7633. /* stripped down version of krb5_mk_req */
  7634. static krb5_error_code
  7635. #ifdef CK_ANSIC
  7636. krb5_renew_tgt(krb5_context context,
  7637. krb5_ccache ccache,
  7638. krb5_principal server, /* tgtname */
  7639. krb5_data *outbuf)
  7640. #else
  7641. krb5_renew_tgt(context, ccache, server, outbuf)
  7642. krb5_context context;
  7643. krb5_ccache ccache;
  7644. krb5_principal server; /* tgtname */
  7645. krb5_data *outbuf;
  7646. #endif
  7647. {
  7648. return krb5_tgt_gen(context, ccache, server, outbuf, RENEW);
  7649. }
  7650. /* stripped down version of krb5_mk_req */
  7651. static krb5_error_code
  7652. #ifdef CK_ANSIC
  7653. krb5_tgt_gen(krb5_context context,
  7654. krb5_ccache ccache,
  7655. krb5_principal server, /* tgtname */
  7656. krb5_data *outbuf,
  7657. int opt)
  7658. #else
  7659. krb5_tgt_gen(context, ccache, server, outbuf, opt)
  7660. krb5_context context;
  7661. krb5_ccache ccache;
  7662. krb5_principal server; /* tgtname */
  7663. krb5_data *outbuf;
  7664. int opt;
  7665. #endif
  7666. {
  7667. krb5_error_code retval;
  7668. krb5_creds * credsp;
  7669. krb5_creds creds;
  7670. /* obtain ticket & session key */
  7671. memset((char *)&creds, 0, sizeof(creds));
  7672. if ((retval = krb5_copy_principal(context, server, &creds.server)))
  7673. goto cleanup;
  7674. if ((retval = krb5_cc_get_principal(context, ccache, &creds.client)))
  7675. goto cleanup_creds;
  7676. if (opt == VALIDATE) {
  7677. if ((retval = krb5_get_credentials_validate(context, 0,
  7678. ccache, &creds, &credsp)))
  7679. goto cleanup_creds;
  7680. } else {
  7681. if ((retval = krb5_get_credentials_renew(context, 0,
  7682. ccache, &creds, &credsp)))
  7683. goto cleanup_creds;
  7684. }
  7685. /* we don't actually need to do the mk_req, just get the creds. */
  7686. cleanup_creds:
  7687. krb5_free_cred_contents(context, &creds);
  7688. cleanup:
  7689. return retval;
  7690. }
  7691. #endif /* HEIMDAL */
  7692. #endif /* KINIT */
  7693. #ifdef KDESTROY
  7694. int
  7695. #ifdef CK_ANSIC
  7696. ck_krb5_destroy(struct krb_op_data * op)
  7697. #else
  7698. ck_krb5_destroy(op) struct krb_op_data * op;
  7699. #endif
  7700. {
  7701. krb5_context kcontext;
  7702. krb5_error_code retval;
  7703. int c;
  7704. krb5_ccache ccache = NULL;
  7705. char *cache_name = NULL;
  7706. int code;
  7707. int errflg=0;
  7708. int quiet = 0;
  7709. if ( !ck_krb5_is_installed() )
  7710. return(-1);
  7711. code = krb5_init_context(&kcontext);
  7712. if (code) {
  7713. debug(F101,"ck_krb5_destroy while initializing krb5","",code);
  7714. krb5_errno = code;
  7715. makestr(&krb5_errmsg,error_message(krb5_errno));
  7716. return(-1);
  7717. }
  7718. code = k5_get_ccache(kcontext,&ccache,op->cache);
  7719. if (code != 0) {
  7720. debug(F101,"ck_krb5_destroy while getting ccache",
  7721. "",code);
  7722. krb5_free_context(kcontext);
  7723. krb5_errno = code;
  7724. makestr(&krb5_errmsg,error_message(krb5_errno));
  7725. return(-1);
  7726. }
  7727. code = krb5_cc_destroy (kcontext, ccache);
  7728. if (code != 0) {
  7729. debug(F101,"ck_krb5_destroy while destroying cache","",code);
  7730. if ( code == KRB5_FCC_NOFILE )
  7731. printf("No ticket cache to destroy.\r\n");
  7732. else
  7733. printf("Ticket cache NOT destroyed!\r\n");
  7734. krb5_cc_close(kcontext,ccache);
  7735. krb5_free_context(kcontext);
  7736. krb5_errno = code;
  7737. makestr(&krb5_errmsg,error_message(krb5_errno));
  7738. return(-1);
  7739. }
  7740. printf("Tickets destroyed.\r\n");
  7741. /* Do not call krb5_cc_close() because cache has been destroyed */
  7742. krb5_free_context(kcontext);
  7743. krb5_errno = 0;
  7744. makestr(&krb5_errmsg,"OK");
  7745. return (0);
  7746. }
  7747. #else /* KDESTROY */
  7748. #ifdef KRB5
  7749. int
  7750. #ifdef CK_ANSIC
  7751. ck_krb5_destroy(struct krb_op_data * op)
  7752. #else
  7753. ck_krb5_destroy(op) struct krb_op_data * op;
  7754. #endif
  7755. {
  7756. printf("?Not implemented.\r\n");
  7757. return(-1);
  7758. }
  7759. #endif /* KRB5 */
  7760. #endif /* KDESTROY */
  7761. #ifndef KLIST
  7762. #ifdef KRB5
  7763. int
  7764. #ifdef CK_ANSIC
  7765. ck_krb5_list_creds(struct krb_op_data * op, struct krb5_list_cred_data * lc)
  7766. #else
  7767. ck_krb5_list_creds(op,lc)
  7768. struct krb_op_data * op; struct krb5_list_cred_data * lc;
  7769. #endif
  7770. {
  7771. printf("?Not implemented.\r\n");
  7772. return(-1);
  7773. }
  7774. #endif /* KRB5 */
  7775. #else /* KLIST */
  7776. static int show_flags = 0, show_time = 0, status_only = 0, show_keys = 0;
  7777. static int show_etype = 0, show_addr = 0;
  7778. static char *defname;
  7779. static char *progname;
  7780. static krb5_int32 now;
  7781. static int timestamp_width;
  7782. _PROTOTYP(static char * etype_string, (krb5_enctype ));
  7783. _PROTOTYP(static void show_credential,(krb5_context,krb5_creds *));
  7784. _PROTOTYP(static int do_ccache, (krb5_context,char *));
  7785. _PROTOTYP(static int do_keytab, (krb5_context,char *));
  7786. _PROTOTYP(static void printtime, (time_t));
  7787. _PROTOTYP(static void fillit, (int, int));
  7788. #define DEFAULT 0
  7789. #define CCACHE 1
  7790. #define KEYTAB 2
  7791. int
  7792. #ifdef CK_ANSIC
  7793. ck_krb5_list_creds(struct krb_op_data * op, struct krb5_list_cred_data * lc)
  7794. #else
  7795. ck_krb5_list_creds(op,lc)
  7796. struct krb_op_data * op; struct krb5_list_cred_data * lc;
  7797. #endif
  7798. {
  7799. krb5_context kcontext;
  7800. krb5_error_code retval;
  7801. int code;
  7802. char *name = op->cache;
  7803. int mode;
  7804. if ( !ck_krb5_is_installed() )
  7805. return(-1);
  7806. code = krb5_init_context(&kcontext);
  7807. if (code) {
  7808. debug(F101,"ck_krb5_list_creds while initializing krb5","",code);
  7809. krb5_errno = code;
  7810. makestr(&krb5_errmsg,error_message(krb5_errno));
  7811. return(-1);
  7812. }
  7813. name = op->cache;
  7814. mode = DEFAULT;
  7815. show_flags = 0;
  7816. show_time = 0;
  7817. status_only = 0;
  7818. show_keys = 0;
  7819. show_etype = 0;
  7820. show_addr = 0;
  7821. show_flags = lc->flags;
  7822. show_etype = lc->encryption;
  7823. show_addr = lc->addr;
  7824. show_time = 1;
  7825. show_keys = 1;
  7826. mode = CCACHE;
  7827. if ((code = krb5_timeofday(kcontext, &now))) {
  7828. if (!status_only)
  7829. debug(F101,"ck_krb5_list_creds while getting time of day.",
  7830. "",code);
  7831. krb5_free_context(kcontext);
  7832. krb5_errno = code;
  7833. makestr(&krb5_errmsg,error_message(krb5_errno));
  7834. return(-1);
  7835. }
  7836. else {
  7837. char tmp[BUFSIZ];
  7838. if (!krb5_timestamp_to_sfstring(now, tmp, 20, (char *) NULL) ||
  7839. !krb5_timestamp_to_sfstring(now, tmp, sizeof(tmp), (char *) NULL))
  7840. timestamp_width = (int) strlen(tmp);
  7841. else
  7842. timestamp_width = 15;
  7843. }
  7844. if (mode == DEFAULT || mode == CCACHE)
  7845. retval = do_ccache(kcontext,name);
  7846. else
  7847. retval = do_keytab(kcontext,name);
  7848. krb5_free_context(kcontext);
  7849. return(retval);
  7850. }
  7851. static int
  7852. #ifdef CK_ANSIC
  7853. do_keytab(krb5_context kcontext, char * name)
  7854. #else
  7855. do_keytab(kcontext,name) krb5_context kcontext; char * name;
  7856. #endif
  7857. {
  7858. krb5_keytab kt;
  7859. krb5_keytab_entry entry;
  7860. krb5_kt_cursor cursor;
  7861. char buf[BUFSIZ]; /* hopefully large enough for any type */
  7862. char *pname;
  7863. int code = 0;
  7864. if (name == NULL) {
  7865. if ((code = krb5_kt_default(kcontext, &kt))) {
  7866. debug(F101,"ck_krb5_list_creds while getting default keytab",
  7867. "",code);
  7868. krb5_errno = code;
  7869. makestr(&krb5_errmsg,error_message(krb5_errno));
  7870. return(-1);
  7871. }
  7872. } else {
  7873. if ((code = krb5_kt_resolve(kcontext, name, &kt))) {
  7874. debug(F111,"ck_krb5_list_creds while resolving keytab",
  7875. name,code);
  7876. krb5_errno = code;
  7877. makestr(&krb5_errmsg,error_message(krb5_errno));
  7878. return(-1);
  7879. }
  7880. }
  7881. if ((code = krb5_kt_get_name(kcontext, kt, buf, BUFSIZ))) {
  7882. debug(F101,"ck_krb5_list_creds while getting keytab name",
  7883. "",code);
  7884. krb5_errno = code;
  7885. makestr(&krb5_errmsg,error_message(krb5_errno));
  7886. return(-1);
  7887. }
  7888. printf("Keytab name: %s\r\n", buf);
  7889. if ((code = krb5_kt_start_seq_get(kcontext, kt, &cursor))) {
  7890. debug(F101,"ck_krb5_list_creds while starting keytab scan",
  7891. "",code);
  7892. krb5_errno = code;
  7893. makestr(&krb5_errmsg,error_message(krb5_errno));
  7894. return(-1);
  7895. }
  7896. if (show_time) {
  7897. printf("KVNO Timestamp");
  7898. fillit(timestamp_width - sizeof("Timestamp") + 2, (int) ' ');
  7899. printf("Principal\r\n");
  7900. printf("---- ");
  7901. fillit(timestamp_width, (int) '-');
  7902. printf(" ");
  7903. fillit(78 - timestamp_width - sizeof("KVNO"), (int) '-');
  7904. printf("\r\n");
  7905. } else {
  7906. printf("KVNO Principal\r\n");
  7907. printf(
  7908. "---- --------------------------------------------------------------------\
  7909. ------\r\n");
  7910. }
  7911. while ((code = krb5_kt_next_entry(kcontext, kt, &entry, &cursor)) == 0) {
  7912. if ((code = krb5_unparse_name(kcontext, entry.principal, &pname))) {
  7913. debug(F101,"ck_krb5_list_creds while unparsing principal name",
  7914. "",code);
  7915. krb5_errno = code;
  7916. makestr(&krb5_errmsg,error_message(krb5_errno));
  7917. return(-1);
  7918. }
  7919. printf("%4d ", entry.vno);
  7920. if (show_time) {
  7921. printtime(entry.timestamp);
  7922. printf(" ");
  7923. }
  7924. printf("%s", pname);
  7925. if (show_etype)
  7926. printf(" (%s) " ,
  7927. #ifdef HEIMDAL
  7928. etype_string(entry.key.keytype)
  7929. #else /* HEIMDAL */
  7930. etype_string(entry.key.enctype)
  7931. #endif /* HEIMDAL */
  7932. );
  7933. if (show_keys) {
  7934. printf(" (0x");
  7935. {
  7936. int i;
  7937. for (i = 0; i < entry.key.length; i++)
  7938. printf("%02x",
  7939. #ifdef HEIMDAL
  7940. entry.key.keyvalue[i]
  7941. #else /* HEIMDAL */
  7942. entry.key.contents[i]
  7943. #endif /* HEIMDAL */
  7944. );
  7945. }
  7946. printf(")");
  7947. }
  7948. printf("\r\n");
  7949. krb5_free_unparsed_name(kcontext,pname);
  7950. }
  7951. if (code && code != KRB5_KT_END) {
  7952. debug(F101,"ck_krb5_list_creds while scanning keytab",
  7953. "",code);
  7954. krb5_errno = code;
  7955. makestr(&krb5_errmsg,error_message(krb5_errno));
  7956. return(-1);
  7957. }
  7958. if ((code = krb5_kt_end_seq_get(kcontext, kt, &cursor))) {
  7959. debug(F101,"ck_krb5_list_creds while ending keytab scan",
  7960. "",code);
  7961. krb5_errno = code;
  7962. makestr(&krb5_errmsg,error_message(krb5_errno));
  7963. return(-1);
  7964. }
  7965. krb5_errno = 0;
  7966. makestr(&krb5_errmsg,"OK");
  7967. return(0);
  7968. }
  7969. static int
  7970. #ifdef CK_ANSIC
  7971. do_ccache(krb5_context kcontext, char * cc_name)
  7972. #else
  7973. do_ccache(kcontext,name) krb5_context kcontext; char * cc_name;
  7974. #endif
  7975. {
  7976. krb5_ccache cache = NULL;
  7977. krb5_cc_cursor cur;
  7978. krb5_creds creds;
  7979. krb5_principal princ=NULL;
  7980. krb5_flags flags=0;
  7981. krb5_error_code code = 0;
  7982. int exit_status = 0;
  7983. if (status_only)
  7984. /* exit_status is set back to 0 if a valid tgt is found */
  7985. exit_status = 1;
  7986. code = k5_get_ccache(kcontext,&cache,cc_name);
  7987. if (code != 0) {
  7988. debug(F111,"do_ccache while getting ccache",
  7989. error_message(code),code);
  7990. krb5_errno = code;
  7991. makestr(&krb5_errmsg,error_message(krb5_errno));
  7992. return(-1);
  7993. }
  7994. flags = 0; /* turns off OPENCLOSE mode */
  7995. if ((code = krb5_cc_set_flags(kcontext, cache, flags))) {
  7996. if (code == ENOENT) {
  7997. debug(F111,"ck_krb5_list_creds (ticket cache)",
  7998. krb5_cc_get_name(kcontext, cache),code);
  7999. } else {
  8000. debug(F111,
  8001. "ck_krb5_list_creds while setting cache flags (ticket cache)",
  8002. krb5_cc_get_name(kcontext, cache),code);
  8003. }
  8004. printf("No ticket File.\r\n");
  8005. krb5_errno = code;
  8006. makestr(&krb5_errmsg,error_message(krb5_errno));
  8007. krb5_cc_close(kcontext,cache);
  8008. return(-1);
  8009. }
  8010. if ((code = krb5_cc_get_principal(kcontext, cache, &princ))) {
  8011. debug(F101,"ck_krb5_list_creds while retrieving principal name",
  8012. "",code);
  8013. krb5_errno = code;
  8014. makestr(&krb5_errmsg,error_message(krb5_errno));
  8015. krb5_cc_close(kcontext,cache);
  8016. return(-1);
  8017. }
  8018. if ((code = krb5_unparse_name(kcontext, princ, &defname))) {
  8019. debug(F101,"ck_krb5_list_creds while unparsing principal name",
  8020. "",code);
  8021. krb5_errno = code;
  8022. makestr(&krb5_errmsg,error_message(krb5_errno));
  8023. krb5_cc_close(kcontext,cache);
  8024. return(-1);
  8025. }
  8026. if (!status_only) {
  8027. printf("Ticket cache: %s:%s\r\nDefault principal: %s\r\n\r\n",
  8028. krb5_cc_get_type(kcontext, cache),
  8029. krb5_cc_get_name(kcontext, cache), defname);
  8030. printf("Valid starting");
  8031. fillit(timestamp_width - sizeof("Valid starting") + 3,
  8032. (int) ' ');
  8033. printf("Expires");
  8034. fillit(timestamp_width - sizeof("Expires") + 3,
  8035. (int) ' ');
  8036. printf("Service principal\r\n");
  8037. }
  8038. if ((code = krb5_cc_start_seq_get(kcontext, cache, &cur))) {
  8039. debug(F101,"ck_krb5_list_creds while starting to retrieve tickets",
  8040. "",code);
  8041. krb5_errno = code;
  8042. makestr(&krb5_errmsg,error_message(krb5_errno));
  8043. krb5_cc_close(kcontext,cache);
  8044. return(-1);
  8045. }
  8046. while (!(code = krb5_cc_next_cred(kcontext, cache, &cur, &creds))) {
  8047. if (status_only) {
  8048. if (exit_status && creds.server->length == 2 &&
  8049. strcmp(creds.server->realm.data, princ->realm.data) == 0 &&
  8050. strcmp((char *)creds.server->data[0].data, "krbtgt") == 0 &&
  8051. strcmp((char *)creds.server->data[1].data,
  8052. princ->realm.data) == 0 &&
  8053. creds.times.endtime > now)
  8054. exit_status = 0;
  8055. } else {
  8056. show_credential(kcontext, &creds);
  8057. }
  8058. krb5_free_cred_contents(kcontext, &creds);
  8059. }
  8060. printf("\r\n");
  8061. if (code == KRB5_CC_END || code == KRB5_CC_NOTFOUND) {
  8062. if ((code = krb5_cc_end_seq_get(kcontext, cache, &cur))) {
  8063. debug(F101,"ck_krb5_list_creds while finishing ticket retrieval",
  8064. "",code);
  8065. krb5_errno = code;
  8066. makestr(&krb5_errmsg,error_message(krb5_errno));
  8067. krb5_cc_close(kcontext,cache);
  8068. return(-1);
  8069. }
  8070. flags = KRB5_TC_OPENCLOSE; /* turns on OPENCLOSE mode */
  8071. if ((code = krb5_cc_set_flags(kcontext, cache, flags))) {
  8072. debug(F101,"ck_krb5_list_creds while closing ccache",
  8073. "",code);
  8074. krb5_errno = code;
  8075. makestr(&krb5_errmsg,error_message(krb5_errno));
  8076. krb5_cc_close(kcontext,cache);
  8077. return(-1);
  8078. }
  8079. krb5_errno = 0;
  8080. makestr(&krb5_errmsg,"OK");
  8081. krb5_cc_close(kcontext,cache);
  8082. return(0);
  8083. } else {
  8084. debug(F101,"ck_krb5_list_creds while retrieving a ticket","",code);
  8085. krb5_errno = code;
  8086. makestr(&krb5_errmsg,error_message(krb5_errno));
  8087. krb5_cc_close(kcontext,cache);
  8088. return(-1);
  8089. }
  8090. krb5_errno = 0;
  8091. makestr(&krb5_errmsg,"OK");
  8092. krb5_cc_close(kcontext,cache);
  8093. return(0);
  8094. }
  8095. static char *
  8096. #ifdef CK_ANSIC
  8097. #ifdef HEIMDAL
  8098. etype_string(krb5_keytype enctype)
  8099. #else /* HEIMDAL */
  8100. etype_string(krb5_enctype enctype)
  8101. #endif /* HEIMDAL */
  8102. #else
  8103. #ifdef HEIMDAL
  8104. etype_string(enctype) krb5_keytype enctype;
  8105. #else /* HEIMDAL */
  8106. etype_string(enctype) krb5_enctype enctype;
  8107. #endif /* HEIMDAL */
  8108. #endif
  8109. {
  8110. static char buf[12];
  8111. switch (enctype) {
  8112. case ENCTYPE_NULL:
  8113. return "NULL";
  8114. case ENCTYPE_DES_CBC_CRC:
  8115. return "DES-CBC-CRC";
  8116. case ENCTYPE_DES_CBC_MD4:
  8117. return "DES-CBC-MD4";
  8118. case ENCTYPE_DES_CBC_MD5:
  8119. return "DES-CBC-MD5";
  8120. case ENCTYPE_DES_CBC_RAW:
  8121. return "DES-CBC-RAW";
  8122. case ENCTYPE_DES3_CBC_SHA:
  8123. return "DES3-CBC-SHA";
  8124. case ENCTYPE_DES3_CBC_RAW:
  8125. return "DES3-CBC-RAW";
  8126. case ENCTYPE_DES_HMAC_SHA1:
  8127. return "DES-HMAC-SHA1";
  8128. case ENCTYPE_DES3_CBC_SHA1:
  8129. return "DES3-CBC-SHA1";
  8130. case ENCTYPE_AES128_CTS_HMAC_SHA1_96:
  8131. return "AES128_CTS-HMAC-SHA1_96";
  8132. case ENCTYPE_AES256_CTS_HMAC_SHA1_96:
  8133. return "AES256_CTS-HMAC-SHA1_96";
  8134. case ENCTYPE_ARCFOUR_HMAC:
  8135. return "RC4-HMAC-NT";
  8136. case ENCTYPE_ARCFOUR_HMAC_EXP:
  8137. return "RC4-HMAC-NT-EXP";
  8138. case ENCTYPE_UNKNOWN:
  8139. return "UNKNOWN";
  8140. case ENCTYPE_LOCAL_DES3_HMAC_SHA1:
  8141. return "LOCAL-DES3-HMAC-SHA1";
  8142. case ENCTYPE_LOCAL_RC4_MD4:
  8143. return "LOCAL-RC4-MD4";
  8144. default:
  8145. ckmakmsg(buf, sizeof(buf),"etype ", ckitoa(enctype),NULL,NULL);
  8146. return buf;
  8147. break;
  8148. }
  8149. }
  8150. static char *
  8151. #ifdef CK_ANSIC
  8152. flags_string(register krb5_creds *cred)
  8153. #else
  8154. flags_string(cred) register krb5_creds *cred;
  8155. #endif
  8156. {
  8157. static char buf[32];
  8158. int i = 0;
  8159. if (cred->ticket_flags & TKT_FLG_FORWARDABLE)
  8160. buf[i++] = 'F';
  8161. if (cred->ticket_flags & TKT_FLG_FORWARDED)
  8162. buf[i++] = 'f';
  8163. if (cred->ticket_flags & TKT_FLG_PROXIABLE)
  8164. buf[i++] = 'P';
  8165. if (cred->ticket_flags & TKT_FLG_PROXY)
  8166. buf[i++] = 'p';
  8167. if (cred->ticket_flags & TKT_FLG_MAY_POSTDATE)
  8168. buf[i++] = 'D';
  8169. if (cred->ticket_flags & TKT_FLG_POSTDATED)
  8170. buf[i++] = 'd';
  8171. if (cred->ticket_flags & TKT_FLG_INVALID)
  8172. buf[i++] = 'i';
  8173. if (cred->ticket_flags & TKT_FLG_RENEWABLE)
  8174. buf[i++] = 'R';
  8175. if (cred->ticket_flags & TKT_FLG_INITIAL)
  8176. buf[i++] = 'I';
  8177. if (cred->ticket_flags & TKT_FLG_HW_AUTH)
  8178. buf[i++] = 'H';
  8179. if (cred->ticket_flags & TKT_FLG_PRE_AUTH)
  8180. buf[i++] = 'A';
  8181. buf[i] = '\0';
  8182. return(buf);
  8183. }
  8184. static char *
  8185. #ifdef CK_ANSIC
  8186. short_date(long *dp)
  8187. #else
  8188. short_date(dp) long *dp;
  8189. #endif
  8190. {
  8191. register char *cp;
  8192. #ifndef ctime
  8193. extern char *ctime();
  8194. #endif /* ctime */
  8195. cp = ctime(dp) + 4;
  8196. cp[15] = '\0';
  8197. return (cp);
  8198. }
  8199. static VOID
  8200. #ifdef CK_ANSIC
  8201. printtime(time_t tv)
  8202. #else
  8203. printtime(tv) time_t tv;
  8204. #endif
  8205. {
  8206. char timestring[BUFSIZ];
  8207. char format[12];
  8208. char fill;
  8209. fill = ' ';
  8210. sprintf(format,"%%-%ds",timestamp_width); /* safe */
  8211. if (!krb5_timestamp_to_sfstring((krb5_timestamp) tv,
  8212. timestring,
  8213. timestamp_width+1,
  8214. &fill)) {
  8215. printf(format,timestring);
  8216. }
  8217. else {
  8218. printf(format,short_date(&tv));
  8219. }
  8220. }
  8221. static void
  8222. #ifdef CK_ANSIC
  8223. one_addr(krb5_address *a)
  8224. #else
  8225. one_addr(a) krb5_address *a;
  8226. #endif
  8227. {
  8228. struct hostent *h;
  8229. extern tcp_rdns;
  8230. if ((a->addrtype == ADDRTYPE_INET) &&
  8231. (a->length == 4)) {
  8232. if (tcp_rdns != SET_OFF) {
  8233. h = gethostbyaddr(a->contents, 4, AF_INET);
  8234. if (h) {
  8235. #ifdef HADDRLIST
  8236. h = ck_copyhostent(h);
  8237. #endif /* HADDRLIST */
  8238. printf("%s (%d.%d.%d.%d)", h->h_name,
  8239. a->contents[0], a->contents[1],
  8240. a->contents[2], a->contents[3]);
  8241. }
  8242. }
  8243. if (tcp_rdns == SET_OFF || !h) {
  8244. printf("%d.%d.%d.%d", a->contents[0], a->contents[1],
  8245. a->contents[2], a->contents[3]);
  8246. }
  8247. } else {
  8248. printf("unknown addr type %d", a->addrtype);
  8249. }
  8250. }
  8251. static VOID
  8252. #ifdef CK_ANSIC
  8253. show_credential(krb5_context kcontext, register krb5_creds * cred)
  8254. #else
  8255. show_credential(kcontext, cred)
  8256. krb5_context kcontext;
  8257. register krb5_creds * cred;
  8258. #endif
  8259. {
  8260. krb5_error_code retval=0;
  8261. krb5_ticket *tkt=NULL;
  8262. char *name=NULL, *sname=NULL, *flags=NULL;
  8263. int extra_field = 0;
  8264. retval = krb5_unparse_name(kcontext, cred->client, &name);
  8265. if (retval) {
  8266. debug(F101,"ck_krb5_list_creds while unparsing client name","",retval);
  8267. krb5_errno = retval;
  8268. makestr(&krb5_errmsg,error_message(krb5_errno));
  8269. return;
  8270. }
  8271. retval = krb5_unparse_name(kcontext, cred->server, &sname);
  8272. if (retval) {
  8273. debug(F101,"ck_krb5_list_creds while unparsing server name","",retval);
  8274. free(name);
  8275. krb5_errno = retval;
  8276. makestr(&krb5_errmsg,error_message(krb5_errno));
  8277. return;
  8278. }
  8279. if (!cred->times.starttime)
  8280. cred->times.starttime = cred->times.authtime;
  8281. printtime(cred->times.starttime);
  8282. printf(" ");
  8283. if ( time(0) < cred->times.endtime )
  8284. printtime(cred->times.endtime);
  8285. else
  8286. printf("** expired ** ");
  8287. printf(" %s\r\n", sname);
  8288. if (strcmp(name, defname)) {
  8289. printf(" for client %s", name);
  8290. extra_field++;
  8291. }
  8292. if (cred->times.renew_till) {
  8293. if (!extra_field)
  8294. printf(" ");
  8295. else
  8296. printf(", ");
  8297. printf("renew until ");
  8298. printtime(cred->times.renew_till);
  8299. extra_field += 2;
  8300. }
  8301. if (extra_field > 3) {
  8302. printf("\r\n");
  8303. extra_field = 0;
  8304. }
  8305. if (show_flags) {
  8306. flags = flags_string(cred);
  8307. if (flags && *flags) {
  8308. if (!extra_field)
  8309. printf(" ");
  8310. else
  8311. printf(", ");
  8312. printf("Flags: %s", flags);
  8313. extra_field++;
  8314. }
  8315. }
  8316. if (extra_field > 2) {
  8317. printf("\r\n");
  8318. extra_field = 0;
  8319. }
  8320. if (show_etype) {
  8321. retval = decode_krb5_ticket(&cred->ticket, &tkt);
  8322. if (!extra_field)
  8323. printf(" ");
  8324. else
  8325. printf(", ");
  8326. #ifdef HEIMDAL
  8327. printf("Etype (skey, tkt): %s, %s ",
  8328. etype_string(cred->session.keytype),
  8329. etype_string(tkt->enc_part.keytype));
  8330. #else /* HEIMDAL */
  8331. printf("Etype (skey, tkt): %s, %s ",
  8332. etype_string(cred->keyblock.enctype),
  8333. etype_string(tkt->enc_part.enctype));
  8334. #endif /* HEIMDAL */
  8335. krb5_free_ticket(kcontext, tkt);
  8336. extra_field++;
  8337. }
  8338. /* if any additional info was printed, extra_field is non-zero */
  8339. if (extra_field)
  8340. printf("\r\n");
  8341. if ( show_addr ) {
  8342. if (!cred->addresses || !cred->addresses[0]) {
  8343. printf("\tAddresses: (none)\r\n");
  8344. } else {
  8345. int i;
  8346. for (i=0; cred->addresses[i]; i++) {
  8347. if (i)
  8348. printf(" ");
  8349. else
  8350. printf(" Addresses: ");
  8351. one_addr(cred->addresses[i]);
  8352. printf("\r\n");
  8353. }
  8354. }
  8355. }
  8356. krb5_free_unparsed_name(kcontext,name);
  8357. krb5_free_unparsed_name(kcontext,sname);
  8358. krb5_errno = 0;
  8359. makestr(&krb5_errmsg,"OK");
  8360. }
  8361. static VOID
  8362. #ifdef CK_ANSIC
  8363. fillit(int num, int c)
  8364. #else
  8365. fillit(num, c) int num; int c;
  8366. #endif
  8367. {
  8368. int i;
  8369. for (i=0; i<num; i++)
  8370. printf("%c",c);
  8371. }
  8372. #endif /* KLIST */
  8373. #endif /* KRB5 */
  8374. #ifdef KRB4
  8375. #define KDEBUG 1
  8376. int k4debug = 0; /* Kerberos 4 runtime debugging */
  8377. #ifdef KINIT
  8378. #define KRB_DEFAULT_LIFE 120 /* 10 hours in 5 minute intervals */
  8379. #ifdef SNK4
  8380. /* SNK4 is a hardware authentication system used to pre-authenticate */
  8381. /* a ticket getting ticket. We do not support this code at the present */
  8382. /* time in Kermit. */
  8383. void
  8384. get_input(s, size, stream)
  8385. char *s;
  8386. int size;
  8387. FILE *stream;
  8388. {
  8389. char *p;
  8390. if (fgets(s, size, stream) == NULL)
  8391. exit(1);
  8392. if ( (p = strchr(s, '\n')) != NULL)
  8393. *p = '\0';
  8394. }
  8395. #endif /* SNK4 */
  8396. #ifdef COMMENT
  8397. static char
  8398. #ifdef CK_ANSIC
  8399. hex_scan_nybble(char c)
  8400. #else
  8401. hex_scan_nybble(c) char c;
  8402. #endif
  8403. {
  8404. if (c >= '0' && c <= '9')
  8405. return c - '0';
  8406. if (c >= 'A' && c <= 'F')
  8407. return c - 'A' + 10;
  8408. if (c >= 'a' && c <= 'f')
  8409. return c - 'a' + 10;
  8410. return -1;
  8411. }
  8412. /* returns: NULL for ok, pointer to error string for bad input */
  8413. static char*
  8414. #ifdef CK_ANSIC
  8415. hex_scan_four_bytes(char *out, char *in)
  8416. #else
  8417. hex_scan_four_bytes(out, in) char *out; char *in;
  8418. #endif
  8419. {
  8420. int i;
  8421. int c;
  8422. char c1;
  8423. for (i=0; i<8; i++) {
  8424. if(!in[i])
  8425. return "not enough input";
  8426. c = hex_scan_nybble(in[i]);
  8427. if(c<0)
  8428. return "invalid digit";
  8429. c1 = c;
  8430. i++;
  8431. if(!in[i])
  8432. return "not enough input";
  8433. c = hex_scan_nybble(in[i]);
  8434. if(c<0)
  8435. return "invalid digit";
  8436. *out++ = (c1 << 4) + c;
  8437. }
  8438. switch(in[i]) {
  8439. case 0:
  8440. case '\r':
  8441. case '\n':
  8442. return NULL;
  8443. default:
  8444. return "extra characters at end of input";
  8445. }
  8446. }
  8447. #endif /* COMMENT */
  8448. /* ck_krb4_initTGT() returns 0 on success */
  8449. int
  8450. #ifdef CK_ANSIC
  8451. ck_krb4_initTGT(struct krb_op_data * op, struct krb4_init_data * init)
  8452. #else
  8453. ck_krb4_initTGT(op,init)
  8454. struct krb_op_data * op, struct krb4_init_data * init
  8455. #endif
  8456. {
  8457. char aname[ANAME_SZ+1];
  8458. char inst[INST_SZ+1];
  8459. char realm[REALM_SZ+1];
  8460. char *password=NULL;
  8461. char passwd[80]="";
  8462. char *username = NULL;
  8463. char *usernameptr=NULL;
  8464. int iflag, /* Instance */
  8465. rflag, /* Realm */
  8466. vflag, /* Verbose */
  8467. lflag, /* Lifetime */
  8468. pflag, /* Preauth */
  8469. lifetime=KRB_DEFAULT_LIFE, /* Life Time */
  8470. k_errno;
  8471. register char *cp;
  8472. register i;
  8473. if ( !ck_krb4_is_installed() )
  8474. return(-1);
  8475. *inst = *realm = '\0';
  8476. iflag = rflag = vflag = lflag = pflag = 0;
  8477. vflag = init->verbose;
  8478. pflag = init->preauth;
  8479. if ( init->lifetime ) {
  8480. lifetime = init->lifetime<5?1:init->lifetime/5;
  8481. if ( lifetime > 255 ) lifetime = 255;
  8482. }
  8483. else
  8484. lifetime = KRB_DEFAULT_LIFE;
  8485. username = init->principal;
  8486. if (username && username[0] &&
  8487. (k_errno = kname_parse(aname, inst, realm, username))
  8488. != AUTH_SUCCESS) {
  8489. krb4_errno = k_errno;
  8490. makestr(&krb4_errmsg,krb_get_err_text_entry(k_errno));
  8491. printf("%s\r\n", krb_get_err_text_entry(k_errno));
  8492. iflag = rflag = 1;
  8493. username = NULL;
  8494. }
  8495. if ( init->realm ) {
  8496. ckstrncpy(realm,init->realm,REALM_SZ);
  8497. }
  8498. if ( init->instance ) {
  8499. ckstrncpy(inst,init->instance, INST_SZ);
  8500. }
  8501. #ifdef COMMENT
  8502. if ( vflag )
  8503. printf("Kerberos IV initialization\r\n");
  8504. #endif /* COMMENT */
  8505. if (!username || !username[0]) {
  8506. debug(F100,"ck_krb4_initTGT no username specified","",0);
  8507. printf("?Invalid principal specified.\r\n");
  8508. krb4_errno = -1;
  8509. makestr(&krb4_errmsg,"No principal specified");
  8510. return(-1);
  8511. }
  8512. if (!*realm) {
  8513. ckstrncpy(realm,ck_krb4_getrealm(),REALM_SZ);
  8514. }
  8515. if ( init->password )
  8516. password = init->password;
  8517. else {
  8518. char prmpt[80];
  8519. int ok;
  8520. ckmakxmsg(prmpt,sizeof(prmpt),
  8521. "Kerberos 4 Password for ",username,"@",realm,": ",
  8522. NULL,NULL,NULL,NULL,NULL,NULL,NULL);
  8523. ok = uq_txt(NULL,prmpt,2,NULL,passwd,80,NULL,DEFAULT_UQ_TIMEOUT);
  8524. if ( ok )
  8525. password = passwd;
  8526. }
  8527. if (pflag) {
  8528. k_errno = krb_get_pw_in_tkt_preauth( aname, inst, realm,
  8529. "krbtgt", realm,
  8530. lifetime,
  8531. password);
  8532. if (k_errno == -1) { /* preauth method not available */
  8533. k_errno = krb_get_pw_in_tkt(aname,
  8534. inst, realm,
  8535. "krbtgt", realm,
  8536. lifetime,
  8537. password);
  8538. }
  8539. } else {
  8540. k_errno = krb_get_pw_in_tkt(aname,
  8541. inst, realm,
  8542. "krbtgt", realm,
  8543. lifetime,
  8544. password);
  8545. }
  8546. memset(passwd,0,sizeof(passwd));
  8547. if (k_errno) {
  8548. printf("%s for principal %s%s%s@%s\r\n",
  8549. krb_get_err_text_entry(k_errno), aname,
  8550. inst[0]?".":"", inst, realm);
  8551. krb4_errno = k_errno;
  8552. makestr(&krb4_errmsg,krb_get_err_text_entry(k_errno));
  8553. return(-1);
  8554. } else if (vflag) {
  8555. printf("Result from realm %s: ", realm);
  8556. printf("%s\r\n", krb_get_err_text_entry(k_errno));
  8557. }
  8558. krb4_errno = k_errno;
  8559. makestr(&krb4_errmsg,krb_get_err_text_entry(k_errno));
  8560. return(0);
  8561. }
  8562. #endif /* KINIT */
  8563. #ifdef KDESTROY
  8564. int
  8565. #ifdef CK_ANSIC
  8566. ck_krb4_destroy(struct krb_op_data * op)
  8567. #else
  8568. ck_krb4_destroy(op) struct krb_op_data * op;
  8569. #endif
  8570. {
  8571. int k_errno=0;
  8572. if ( !ck_krb4_is_installed() )
  8573. return(-1);
  8574. k_errno = dest_tkt();
  8575. krb4_errno = k_errno;
  8576. makestr(&krb4_errmsg,krb_get_err_text_entry(k_errno));
  8577. if (k_errno == 0)
  8578. printf("Tickets destroyed.\r\n");
  8579. else if (k_errno == RET_TKFIL)
  8580. printf("No tickets to destroy.\r\n");
  8581. else {
  8582. printf("Tickets MAY NOT be destroyed.\r\n");
  8583. return(-1);
  8584. }
  8585. return(0);
  8586. }
  8587. #endif /* KDESTROY */
  8588. #ifdef KLIST
  8589. _PROTOTYP(static int display_tktfile,(char *, int, int, int));
  8590. int
  8591. #ifdef CK_ANSIC
  8592. ck_krb4_list_creds(struct krb_op_data * op)
  8593. #else
  8594. ck_krb4_list_creds(op) struct krb_op_data * op;
  8595. #endif
  8596. {
  8597. int long_form = 1;
  8598. int tgt_test = 0;
  8599. int do_srvtab = 0;
  8600. int show_kvnos = 0;
  8601. char *tkt_file = NULL;
  8602. if ( !ck_krb4_is_installed() )
  8603. return(-1);
  8604. if ( op->cache )
  8605. tkt_file = op->cache;
  8606. if ( k4debug ) {
  8607. show_kvnos = 1;
  8608. }
  8609. if (do_srvtab)
  8610. return(display_srvtab(tkt_file));
  8611. else
  8612. return(display_tktfile(tkt_file, tgt_test, long_form, show_kvnos));
  8613. }
  8614. #ifndef KRB5
  8615. static int timestamp_width=0;
  8616. static char *
  8617. #ifdef CK_ANSIC
  8618. short_date(long *dp)
  8619. #else
  8620. short_date(dp) long *dp;
  8621. #endif
  8622. {
  8623. register char *cp;
  8624. extern char *ctime();
  8625. cp = ctime(dp) + 4;
  8626. cp[15] = '\0';
  8627. return (cp);
  8628. }
  8629. static VOID
  8630. #ifdef CK_ANSIC
  8631. printtime(time_t tv)
  8632. #else
  8633. printtime(tv) time_t tv;
  8634. #endif
  8635. {
  8636. char timestring[BUFSIZ];
  8637. char format[12];
  8638. char fill;
  8639. fill = ' ';
  8640. sprintf(format,"%%-%ds",timestamp_width); /* safe */
  8641. printf(format,short_date(&tv));
  8642. }
  8643. #endif /* KRB5 */
  8644. static int
  8645. #ifdef CK_ANSIC
  8646. display_tktfile(char *file, int tgt_test, int long_form, int show_kvnos)
  8647. #else
  8648. display_tktfile(file,tgt_test,long_form,show_kvnos)
  8649. char *file; int tgt_test; int long_form; int show_kvnos;
  8650. #endif
  8651. {
  8652. char pname[ANAME_SZ];
  8653. char pinst[INST_SZ];
  8654. char prealm[REALM_SZ];
  8655. char buf1[20], buf2[20];
  8656. int k_errno;
  8657. #ifdef OS2
  8658. LEASH_CREDENTIALS creds;
  8659. #else /* OS2 */
  8660. CREDENTIALS creds;
  8661. #endif /* OS2 */
  8662. int header = 1;
  8663. file = tkt_string();
  8664. if (long_form) {
  8665. printf("Ticket cache: %s\r\n", file);
  8666. }
  8667. /*
  8668. * Since krb_get_tf_realm will return a ticket_file error,
  8669. * we will call tf_init and tf_close first to filter out
  8670. * things like no ticket file. Otherwise, the error that
  8671. * the user would see would be
  8672. * klist: can't find realm of ticket file: No ticket file (tf_util)
  8673. * instead of
  8674. * klist: No ticket file (tf_util)
  8675. */
  8676. /* Open ticket file */
  8677. if (k_errno = tf_init(file, R_TKT_FIL)) {
  8678. if (!tgt_test)
  8679. printf("%s\r\n", krb_get_err_text_entry (k_errno));
  8680. krb4_errno = k_errno;
  8681. makestr(&krb4_errmsg,krb_get_err_text_entry(k_errno));
  8682. return(-1);
  8683. }
  8684. /* Close ticket file */
  8685. (void) tf_close();
  8686. /*
  8687. * We must find the realm of the ticket file here before calling
  8688. * tf_init because since the realm of the ticket file is not
  8689. * really stored in the principal section of the file, the
  8690. * routine we use must itself call tf_init and tf_close.
  8691. */
  8692. if ((k_errno = krb_get_tf_realm(file, prealm)) != AUTH_SUCCESS) {
  8693. if (!tgt_test)
  8694. printf("can't find realm of ticket file: %s\r\n",
  8695. krb_get_err_text_entry (k_errno));
  8696. krb4_errno = k_errno;
  8697. makestr(&krb4_errmsg,krb_get_err_text_entry(k_errno));
  8698. return(-1);
  8699. }
  8700. /* Open ticket file */
  8701. if (k_errno = tf_init(file, R_TKT_FIL)) {
  8702. if (!tgt_test)
  8703. printf("%s\r\n", krb_get_err_text_entry (k_errno));
  8704. krb4_errno = k_errno;
  8705. makestr(&krb4_errmsg,krb_get_err_text_entry(k_errno));
  8706. return(-1);
  8707. }
  8708. /* Get principal name and instance */
  8709. if ((k_errno = tf_get_pname(pname)) ||
  8710. (k_errno = tf_get_pinst(pinst))) {
  8711. (void) tf_close();
  8712. if (!tgt_test)
  8713. printf("%s\r\n", krb_get_err_text_entry (k_errno));
  8714. krb4_errno = k_errno;
  8715. makestr(&krb4_errmsg,krb_get_err_text_entry(k_errno));
  8716. return(-1);
  8717. }
  8718. /*
  8719. * You may think that this is the obvious place to get the
  8720. * realm of the ticket file, but it can't be done here as the
  8721. * routine to do this must open the ticket file. This is why
  8722. * it was done before tf_init.
  8723. */
  8724. if (!tgt_test && long_form)
  8725. printf("Default principal: %s%s%s%s%s\r\n\r\n", pname,
  8726. (pinst[0] ? "." : ""), pinst,
  8727. (prealm[0] ? "@" : ""), prealm);
  8728. while ((k_errno = tf_get_cred(&creds)) == AUTH_SUCCESS) {
  8729. if (!tgt_test && long_form && header) {
  8730. printf("%-17s %-17s %s\r\n",
  8731. "Valid starting", "Expires", "Service principal");
  8732. header = 0;
  8733. }
  8734. if (tgt_test) {
  8735. creds.issue_date += ((unsigned char) creds.lifetime) * 5 * 60;
  8736. if (!strcmp(creds.service, "krbtgt") &&
  8737. !strcmp(creds.instance, prealm)) {
  8738. krb4_errno = k_errno;
  8739. makestr(&krb4_errmsg,krb_get_err_text_entry(k_errno));
  8740. (void) tf_close();
  8741. if (time(0) < creds.issue_date) {
  8742. return(0); /* tgt hasn't expired */
  8743. } else {
  8744. return(-1); /* has expired */
  8745. }
  8746. }
  8747. continue; /* not a tgt */
  8748. }
  8749. if (long_form) {
  8750. timestamp_width = 17; /* for k5 display function */
  8751. /* if available */
  8752. printtime(creds.issue_date);
  8753. printf(" ");
  8754. creds.issue_date += ((unsigned char) creds.lifetime) * 5 * 60;
  8755. if ( time(0) < creds.issue_date )
  8756. printtime(creds.issue_date);
  8757. else
  8758. printf("*** expired *** ");
  8759. printf(" ");
  8760. }
  8761. if (show_kvnos)
  8762. printf("%s%s%s%s%s (%d)\r\n",
  8763. creds.service, (creds.instance[0] ? "." : ""), creds.instance,
  8764. (creds.realm[0] ? "@" : ""), creds.realm, creds.kvno);
  8765. else
  8766. printf("%s%s%s%s%s\r\n",
  8767. creds.service, (creds.instance[0] ? "." : ""), creds.instance,
  8768. (creds.realm[0] ? "@" : ""), creds.realm);
  8769. #ifdef OS2
  8770. if ( creds.address[0] )
  8771. printf(" Address: %s\r\n",creds.address);
  8772. #endif /* OS2 */
  8773. }
  8774. (void) tf_close();
  8775. if (tgt_test) {
  8776. return(-1);
  8777. }/* no tgt found */
  8778. if (header && long_form && k_errno == EOF) {
  8779. printf("No tickets in file.\r\n");
  8780. }
  8781. krb4_errno = k_errno;
  8782. makestr(&krb4_errmsg,krb_get_err_text_entry(k_errno));
  8783. return(0);
  8784. }
  8785. #ifdef COMMENT
  8786. /* Just so we remember what the command line interface looked like */
  8787. usage()
  8788. {
  8789. printf(
  8790. "Usage: [ -s | -t ] [ -file filename ] [ -srvtab ] [ -version ]\r\n");
  8791. return(-1);
  8792. }
  8793. #endif /* COMMENT */
  8794. /* adapted from getst() in librkb */
  8795. /*
  8796. * ok_getst() takes a file descriptor, a string and a count. It reads
  8797. * from the file until either it has read "count" characters, or until
  8798. * it reads a null byte. When finished, what has been read exists in
  8799. * the given string "s". If "count" characters were actually read, the
  8800. * last is changed to a null, so the returned string is always null-
  8801. * terminated. ok_getst() returns the number of characters read, including
  8802. * the null terminator.
  8803. *
  8804. * If there is a read error, it returns -1 (like the read(2) system call)
  8805. */
  8806. static int
  8807. #ifdef CK_ANSIC
  8808. ok_getst(int fd, register char *s, int n)
  8809. #else
  8810. ok_getst(fd, s, n) int fd; register char *s; int n;
  8811. #endif
  8812. {
  8813. register int count = n;
  8814. int err;
  8815. while ((err = read(fd, s, 1)) > 0 && --count)
  8816. if (*s++ == '\0')
  8817. return (n - count);
  8818. if (err < 0)
  8819. return(-1);
  8820. *s = '\0';
  8821. return (n - count);
  8822. }
  8823. int
  8824. #ifdef CK_ANSIC
  8825. display_srvtab(char *file)
  8826. #else
  8827. display_srvtab(file) char *file;
  8828. #endif
  8829. {
  8830. int stab;
  8831. char serv[SNAME_SZ];
  8832. char inst[INST_SZ];
  8833. char rlm[REALM_SZ];
  8834. unsigned char key[8];
  8835. unsigned char vno;
  8836. int count;
  8837. printf("Server key file: %s\r\n", file);
  8838. #ifdef NT
  8839. #ifndef O_RDONLY
  8840. #define O_RDONLY _O_RDONLY
  8841. #endif /* O_RDONLY */
  8842. #endif /* NT */
  8843. if ((stab = open(file, O_RDONLY, 0400)) < 0) {
  8844. perror(file);
  8845. return(-1);
  8846. }
  8847. printf("%-15s %-15s %-10s %s\r\n","Service","Instance","Realm",
  8848. "Key Version");
  8849. printf("------------------------------------------------------\r\n");
  8850. /* argh. getst doesn't return error codes, it silently fails */
  8851. while (((count = ok_getst(stab, serv, SNAME_SZ)) > 0)
  8852. && ((count = ok_getst(stab, inst, INST_SZ)) > 0)
  8853. && ((count = ok_getst(stab, rlm, REALM_SZ)) > 0)) {
  8854. if (((count = read(stab,(char *) &vno,1)) != 1) ||
  8855. ((count = read(stab,(char *) key,8)) != 8)) {
  8856. if (count < 0)
  8857. perror("reading from key file");
  8858. else
  8859. printf("key file truncated\r\n");
  8860. return(-1);
  8861. }
  8862. printf("%-15s %-15s %-15s %d\r\n",serv,inst,rlm,vno);
  8863. }
  8864. if (count < 0)
  8865. perror(file);
  8866. (void) close(stab);
  8867. return(0);
  8868. }
  8869. #endif /* KLIST */
  8870. #else /* KRB4 */
  8871. int
  8872. ck_krb4_autoget_TGT(char * dummy)
  8873. {
  8874. return(-1);
  8875. }
  8876. #ifdef CK_KERBEROS
  8877. int
  8878. #ifdef CK_ANSIC
  8879. ck_krb4_initTGT(struct krb_op_data * op, struct krb4_init_data * init)
  8880. #else
  8881. ck_krb4_initTGT(op,init)
  8882. struct krb_op_data * op, struct krb4_init_data * init
  8883. #endif
  8884. {
  8885. return(-1);
  8886. }
  8887. #ifdef CK_ANSIC
  8888. ck_krb4_destroy(struct krb_op_data * op)
  8889. #else
  8890. ck_krb4_destroy(op) struct krb_op_data * op;
  8891. #endif
  8892. {
  8893. return(-1);
  8894. }
  8895. int
  8896. #ifdef CK_ANSIC
  8897. ck_krb4_list_creds(struct krb_op_data * op)
  8898. #else
  8899. ck_krb4_list_creds(op) struct krb_op_data * op;
  8900. #endif
  8901. {
  8902. return(-1);
  8903. }
  8904. #else /* CK_KERBEROS */
  8905. int ck_krb4_initTGT(void * a, void *b)
  8906. {
  8907. return(-1);
  8908. }
  8909. int ck_krb4_destroy(void *a)
  8910. {
  8911. return(-1);
  8912. }
  8913. int ck_krb4_list_creds(void *a)
  8914. {
  8915. return(-1);
  8916. }
  8917. #endif /* CK_KERBEROS */
  8918. #endif /* KRB4 */
  8919. /* The following functions are used to implement the Kermit Script Language */
  8920. /* functions */
  8921. struct tkt_list_item {
  8922. char * name;
  8923. struct tkt_list_item * next;
  8924. };
  8925. static struct tkt_list_item * k4_tkt_list = NULL;
  8926. int
  8927. #ifdef CK_ANSIC
  8928. ck_krb4_get_tkts(VOID)
  8929. #else
  8930. ck_krb4_get_tkts()
  8931. #endif
  8932. {
  8933. #ifdef KRB4
  8934. char *file=NULL;
  8935. char pname[ANAME_SZ];
  8936. char pinst[INST_SZ];
  8937. char prealm[REALM_SZ];
  8938. char buf1[20], buf2[20];
  8939. int k_errno;
  8940. #ifdef OS2
  8941. LEASH_CREDENTIALS creds;
  8942. #else /* OS2 */
  8943. CREDENTIALS creds;
  8944. #endif /* OS2 */
  8945. int tkt_count=0;
  8946. struct tkt_list_item ** list = &k4_tkt_list;
  8947. while ( k4_tkt_list ) {
  8948. struct tkt_list_item * next;
  8949. next = k4_tkt_list->next;
  8950. free(k4_tkt_list->name);
  8951. free(k4_tkt_list);
  8952. k4_tkt_list = next;
  8953. }
  8954. if ( !ck_krb4_is_installed() )
  8955. return(-1);
  8956. file = tkt_string();
  8957. /*
  8958. * Since krb_get_tf_realm will return a ticket_file error,
  8959. * we will call tf_init and tf_close first to filter out
  8960. * things like no ticket file. Otherwise, the error that
  8961. * the user would see would be
  8962. * klist: can't find realm of ticket file: No ticket file (tf_util)
  8963. * instead of
  8964. * klist: No ticket file (tf_util)
  8965. */
  8966. /* Open ticket file */
  8967. if (k_errno = tf_init(file, R_TKT_FIL)) {
  8968. return(-1);
  8969. }
  8970. /* Close ticket file */
  8971. (void) tf_close();
  8972. /*
  8973. * We must find the realm of the ticket file here before calling
  8974. * tf_init because since the realm of the ticket file is not
  8975. * really stored in the principal section of the file, the
  8976. * routine we use must itself call tf_init and tf_close.
  8977. */
  8978. if ((k_errno = krb_get_tf_realm(file, prealm)) != AUTH_SUCCESS) {
  8979. return(-1);
  8980. }
  8981. /* Open ticket file */
  8982. if (k_errno = tf_init(file, R_TKT_FIL)) {
  8983. return(-1);
  8984. }
  8985. /* Get principal name and instance */
  8986. if ((k_errno = tf_get_pname(pname)) ||
  8987. (k_errno = tf_get_pinst(pinst))) {
  8988. return(-1);
  8989. }
  8990. /*
  8991. * You may think that this is the obvious place to get the
  8992. * realm of the ticket file, but it can't be done here as the
  8993. * routine to do this must open the ticket file. This is why
  8994. * it was done before tf_init.
  8995. */
  8996. while ((k_errno = tf_get_cred(&creds)) == AUTH_SUCCESS) {
  8997. char tkt_buf[256];
  8998. ckmakxmsg(tkt_buf,sizeof(tkt_buf),
  8999. creds.service, (creds.instance[0] ? "." : ""), creds.instance,
  9000. (creds.realm[0] ? "@" : ""), creds.realm,
  9001. NULL,NULL,NULL,NULL,NULL,NULL,NULL);
  9002. *list = (struct tkt_list_item *) malloc(sizeof(struct tkt_list_item));
  9003. (*list)->name = strdup(tkt_buf);
  9004. (*list)->next = NULL;
  9005. list = &((*list)->next);
  9006. tkt_count++;
  9007. }
  9008. tf_close();
  9009. return(tkt_count);
  9010. #else /* KRB4 */
  9011. return(0);
  9012. #endif /* KRB4 */
  9013. }
  9014. char *
  9015. #ifdef CK_ANSIC
  9016. ck_krb4_get_next_tkt(VOID)
  9017. #else
  9018. ck_krb4_get_next_tkt()
  9019. #endif
  9020. {
  9021. #ifdef KRB4
  9022. static char * s=NULL;
  9023. struct tkt_list_item * next=NULL;
  9024. if ( s ) {
  9025. free(s);
  9026. s = NULL;
  9027. }
  9028. if ( k4_tkt_list == NULL )
  9029. return(NULL);
  9030. next = k4_tkt_list->next;
  9031. s = k4_tkt_list->name;
  9032. free(k4_tkt_list);
  9033. k4_tkt_list = next;
  9034. return(s);
  9035. #else /* KRB4 */
  9036. return(NULL);
  9037. #endif /* KRB4 */
  9038. }
  9039. int
  9040. #ifdef CK_ANSIC
  9041. ck_krb4_tkt_isvalid(char * tktname)
  9042. #else
  9043. ck_krb4_tkt_isvalid(tktname) char * tktname;
  9044. #endif
  9045. {
  9046. #ifdef KRB4
  9047. char *file=NULL;
  9048. char pname[ANAME_SZ];
  9049. char pinst[INST_SZ];
  9050. char prealm[REALM_SZ];
  9051. char buf1[20], buf2[20];
  9052. int k_errno;
  9053. time_t issue_t, expire_t, now_t;
  9054. #ifdef OS2
  9055. LEASH_CREDENTIALS creds;
  9056. #else /* OS2 */
  9057. CREDENTIALS creds;
  9058. #endif /* OS2 */
  9059. if ( !ck_krb4_is_installed() )
  9060. return(-1);
  9061. debug(F110,"ck_krb4_tkt_isvalid","tkt_string",0);
  9062. file = tkt_string();
  9063. /*
  9064. * Since krb_get_tf_realm will return a ticket_file error,
  9065. * we will call tf_init and tf_close first to filter out
  9066. * things like no ticket file. Otherwise, the error that
  9067. * the user would see would be
  9068. * klist: can't find realm of ticket file: No ticket file (tf_util)
  9069. * instead of
  9070. * klist: No ticket file (tf_util)
  9071. */
  9072. /* Open ticket file */
  9073. debug(F110,"ck_krb4_tkt_isvalid","tf_init",0);
  9074. if (k_errno = tf_init(file, R_TKT_FIL)) {
  9075. return(-1);
  9076. }
  9077. /* Close ticket file */
  9078. debug(F110,"ck_krb4_tkt_isvalid","tf_close",0);
  9079. (void) tf_close();
  9080. /*
  9081. * We must find the realm of the ticket file here before calling
  9082. * tf_init because since the realm of the ticket file is not
  9083. * really stored in the principal section of the file, the
  9084. * routine we use must itself call tf_init and tf_close.
  9085. */
  9086. debug(F110,"ck_krb4_tkt_isvalid","krb_get_tf_realm",0);
  9087. if ((k_errno = krb_get_tf_realm(file, prealm)) != AUTH_SUCCESS) {
  9088. return(-1);
  9089. }
  9090. /* Open ticket file */
  9091. debug(F110,"ck_krb4_tkt_isvalid","tf_init",0);
  9092. if (k_errno = tf_init(file, R_TKT_FIL)) {
  9093. return(-1);
  9094. }
  9095. /* Get principal name and instance */
  9096. debug(F110,"ck_krb4_tkt_isvalid","tf_get_name/tf_get_pinst",0);
  9097. if ((k_errno = tf_get_pname(pname)) ||
  9098. (k_errno = tf_get_pinst(pinst))) {
  9099. /* Close ticket file */
  9100. debug(F110,"ck_krb4_tkt_isvalid","tf_close",0);
  9101. (void) tf_close();
  9102. return(-1);
  9103. }
  9104. /*
  9105. * You may think that this is the obvious place to get the
  9106. * realm of the ticket file, but it can't be done here as the
  9107. * routine to do this must open the ticket file. This is why
  9108. * it was done before tf_init.
  9109. */
  9110. debug(F110,"ck_krb4_tkt_isvalid","tf_get_cred",0);
  9111. while ((k_errno = tf_get_cred(&creds)) == AUTH_SUCCESS) {
  9112. char tkt_buf[256];
  9113. ckmakxmsg(tkt_buf,sizeof(tkt_buf),
  9114. creds.service, (creds.instance[0] ? "." : ""), creds.instance,
  9115. (creds.realm[0] ? "@" : ""), creds.realm,
  9116. NULL,NULL,NULL,NULL,NULL,NULL,NULL);
  9117. if ( !strcmp(tktname,tkt_buf) ) {
  9118. /* we found the ticket we are looking for */
  9119. issue_t = creds.issue_date;
  9120. expire_t = creds.issue_date
  9121. + ((unsigned char) creds.lifetime) * 5 * 60;
  9122. now_t = time(0);
  9123. /* We add a 5 minutes fudge factor to compensate for potential */
  9124. /* clock skew errors between the KDC and K95's host OS */
  9125. if ( now_t >= (issue_t-300) && now_t < expire_t) {
  9126. #ifdef OS2
  9127. #ifdef CHECKADDRS
  9128. if ( krb4_checkaddrs ) {
  9129. extern char myipaddr[20]; /* From ckcnet.c */
  9130. if ( !myipaddr[0] ) {
  9131. int i;
  9132. char buf[60];
  9133. for ( i=0;i<64;i++ ) {
  9134. if ( getlocalipaddrs(buf,60,i) < 0 )
  9135. break;
  9136. if ( !strcmp(buf,creds.address) ) {
  9137. /* Close ticket file */
  9138. debug(F110,"ck_krb4_tkt_isvalid","tf_close",0);
  9139. (void) tf_close();
  9140. return(1); /* They're the same */
  9141. }
  9142. }
  9143. /* Close ticket file */
  9144. debug(F110,"ck_krb4_tkt_isvalid","tf_close",0);
  9145. (void) tf_close();
  9146. return(0); /* They're different */
  9147. } else if ( strcmp(myipaddr,creds.address) ) {
  9148. /* Close ticket file */
  9149. debug(F110,"ck_krb4_tkt_isvalid","tf_close",0);
  9150. (void) tf_close();
  9151. return(0); /* They're different */
  9152. }
  9153. else {
  9154. /* Close ticket file */
  9155. debug(F110,"ck_krb4_tkt_isvalid","tf_close",0);
  9156. (void) tf_close();
  9157. return(1); /* They're the same */
  9158. }
  9159. } else {
  9160. /* Close ticket file */
  9161. debug(F110,"ck_krb4_tkt_isvalid","tf_close",0);
  9162. (void) tf_close();
  9163. return(1); /* They're the same */
  9164. }
  9165. #else /* CHECKADDRS */
  9166. /* Close ticket file */
  9167. debug(F110,"ck_krb4_tkt_isvalid","tf_close",0);
  9168. (void) tf_close();
  9169. return(1); /* valid but no ip address check */
  9170. #endif /* CHECKADDRS */
  9171. #else /* OS2 */
  9172. /* Close ticket file */
  9173. debug(F110,"ck_krb4_tkt_isvalid","tf_close",0);
  9174. (void) tf_close();
  9175. return(1); /* Valid but no ip address check */
  9176. #endif /* OS2 */
  9177. }
  9178. else {
  9179. /* Close ticket file */
  9180. debug(F110,"ck_krb4_tkt_isvalid","tf_close",0);
  9181. (void) tf_close();
  9182. return(0); /* expired or otherwise invalid */
  9183. }
  9184. }
  9185. }
  9186. /* Close ticket file */
  9187. debug(F110,"ck_krb4_tkt_isvalid","tf_close",0);
  9188. (void) tf_close();
  9189. return(0); /* could not find the desired ticket */
  9190. #else /* KRB4 */
  9191. return(-1);
  9192. #endif /* KRB4 */
  9193. }
  9194. int
  9195. #ifdef CK_ANSIC
  9196. ck_krb4_is_tgt_valid(VOID)
  9197. #else
  9198. ck_krb4_is_tgt_valid()
  9199. #endif
  9200. {
  9201. #ifdef KRB4
  9202. char tgt[256];
  9203. char * s;
  9204. int rc = 0;
  9205. s = krb4_d_realm ? krb4_d_realm : ck_krb4_getrealm();
  9206. ckmakmsg(tgt,sizeof(tgt),"krbtgt.",s,"@",s);
  9207. rc = ck_krb4_tkt_isvalid(tgt);
  9208. debug(F111,"ck_krb4_is_tgt_valid",tgt,rc);
  9209. return(rc > 0);
  9210. #else /* KRB4 */
  9211. return(0);
  9212. #endif /* KRB4 */
  9213. }
  9214. int
  9215. #ifdef CK_ANSIC
  9216. ck_krb4_tkt_time(char * tktname)
  9217. #else
  9218. ck_krb4_tkt_time(tktname) char * tktname;
  9219. #endif
  9220. {
  9221. #ifdef KRB4
  9222. char *file=NULL;
  9223. char pname[ANAME_SZ];
  9224. char pinst[INST_SZ];
  9225. char prealm[REALM_SZ];
  9226. char buf1[20], buf2[20];
  9227. int k_errno;
  9228. #ifdef OS2
  9229. LEASH_CREDENTIALS creds;
  9230. #else /* OS2 */
  9231. CREDENTIALS creds;
  9232. #endif /* OS2 */
  9233. if ( !ck_krb4_is_installed() )
  9234. return(-1);
  9235. file = tkt_string();
  9236. /*
  9237. * Since krb_get_tf_realm will return a ticket_file error,
  9238. * we will call tf_init and tf_close first to filter out
  9239. * things like no ticket file. Otherwise, the error that
  9240. * the user would see would be
  9241. * klist: can't find realm of ticket file: No ticket file (tf_util)
  9242. * instead of
  9243. * klist: No ticket file (tf_util)
  9244. */
  9245. /* Open ticket file */
  9246. if (k_errno = tf_init(file, R_TKT_FIL)) {
  9247. return(-1);
  9248. }
  9249. /* Close ticket file */
  9250. (void) tf_close();
  9251. /*
  9252. * We must find the realm of the ticket file here before calling
  9253. * tf_init because since the realm of the ticket file is not
  9254. * really stored in the principal section of the file, the
  9255. * routine we use must itself call tf_init and tf_close.
  9256. */
  9257. if ((k_errno = krb_get_tf_realm(file, prealm)) != AUTH_SUCCESS) {
  9258. return(-1);
  9259. }
  9260. /* Open ticket file */
  9261. if (k_errno = tf_init(file, R_TKT_FIL)) {
  9262. return(-1);
  9263. }
  9264. /* Get principal name and instance */
  9265. if ((k_errno = tf_get_pname(pname)) ||
  9266. (k_errno = tf_get_pinst(pinst))) {
  9267. tf_close();
  9268. return(-1);
  9269. }
  9270. /*
  9271. * You may think that this is the obvious place to get the
  9272. * realm of the ticket file, but it can't be done here as the
  9273. * routine to do this must open the ticket file. This is why
  9274. * it was done before tf_init.
  9275. */
  9276. while ((k_errno = tf_get_cred(&creds)) == AUTH_SUCCESS) {
  9277. char tkt_buf[256];
  9278. ckmakxmsg(tkt_buf,sizeof(tkt_buf),
  9279. creds.service, (creds.instance[0] ? "." : ""),
  9280. creds.instance,
  9281. (creds.realm[0] ? "@" : ""), creds.realm,
  9282. NULL,NULL,NULL,NULL,NULL,NULL,NULL);
  9283. if ( !strcmp(tktname,tkt_buf) ) {
  9284. /* we found the ticket we are looking for */
  9285. int n = (creds.issue_date
  9286. + (((unsigned char) creds.lifetime) * 5 * 60))
  9287. - time(0);
  9288. tf_close();
  9289. return(n <= 0 ? 0 : n);
  9290. }
  9291. }
  9292. tf_close();
  9293. return(0); /* could not find the desired ticket */
  9294. #else /* KRB4 */
  9295. return(-1);
  9296. #endif /* KRB4 */
  9297. }
  9298. char *
  9299. #ifdef CK_ANSIC
  9300. ck_krb4_getrealm(void)
  9301. #else
  9302. ck_krb4_getrealm()
  9303. #endif
  9304. {
  9305. #ifdef KRB4
  9306. char *file=NULL;
  9307. int k_errno;
  9308. static char realm[256]="";
  9309. realm[0]='\0';
  9310. if ( !ck_krb4_is_installed() )
  9311. return(realm);
  9312. /* Try to get realm from ticket file */
  9313. /* If failure get the local realm */
  9314. /*
  9315. * Since krb_get_tf_realm will return a ticket_file error,
  9316. * we will call tf_init and tf_close first to filter out
  9317. * things like no ticket file.
  9318. */
  9319. /* Open ticket file */
  9320. file = tkt_string();
  9321. if (file == NULL || !file[0])
  9322. return(realm);
  9323. if ((k_errno = tf_init(file, R_TKT_FIL)) == KSUCCESS) {
  9324. /* Close ticket file */
  9325. (void) tf_close();
  9326. k_errno = krb_get_tf_realm(file, realm);
  9327. }
  9328. if (k_errno != KSUCCESS) {
  9329. k_errno = krb_get_lrealm(realm, 1);
  9330. }
  9331. return(realm);
  9332. #else /* KRB4 */
  9333. return("");
  9334. #endif /* KRB4 */
  9335. }
  9336. char *
  9337. #ifdef CK_ANSIC
  9338. ck_krb4_getprincipal(void)
  9339. #else
  9340. ck_krb4_getprincipal()
  9341. #endif
  9342. {
  9343. #ifdef KRB4
  9344. char *file=NULL;
  9345. int k_errno;
  9346. static char principal[256]="";
  9347. char instance[256]="";
  9348. char realm[256]="";
  9349. principal[0]='\0';
  9350. if ( !ck_krb4_is_installed() )
  9351. return(principal);
  9352. /* Try to get realm from ticket file */
  9353. /* If failure get the local realm */
  9354. /*
  9355. * Since krb_get_tf_realm will return a ticket_file error,
  9356. * we will call tf_init and tf_close first to filter out
  9357. * things like no ticket file.
  9358. */
  9359. /* Open ticket file */
  9360. file = tkt_string();
  9361. if (file == NULL || !file[0])
  9362. return(principal);
  9363. if ((k_errno = tf_init(file, R_TKT_FIL)) == KSUCCESS) {
  9364. /* Close ticket file */
  9365. (void) tf_close();
  9366. k_errno = krb_get_tf_fullname(file, principal, instance, realm);
  9367. }
  9368. return(principal);
  9369. #else /* KRB4 */
  9370. return("");
  9371. #endif /* KRB4 */
  9372. }
  9373. static struct tkt_list_item * k5_tkt_list = NULL;
  9374. int
  9375. #ifdef CK_ANSIC
  9376. ck_krb5_get_tkts(char * cc_name)
  9377. #else
  9378. ck_krb5_get_tkts(cc_name) char * cc_name;
  9379. #endif
  9380. {
  9381. #ifdef KRB5
  9382. #ifndef HEIMDAL
  9383. krb5_context kcontext;
  9384. krb5_error_code retval;
  9385. krb5_ccache cache = NULL;
  9386. krb5_cc_cursor cur;
  9387. krb5_creds creds;
  9388. krb5_principal princ=NULL;
  9389. krb5_flags flags=0;
  9390. krb5_error_code code=0;
  9391. int exit_status = 0;
  9392. int tkt_count=0;
  9393. struct tkt_list_item ** list = &k5_tkt_list;
  9394. while ( k5_tkt_list ) {
  9395. struct tkt_list_item * next;
  9396. next = k5_tkt_list->next;
  9397. free(k5_tkt_list->name);
  9398. free(k5_tkt_list);
  9399. k5_tkt_list = next;
  9400. }
  9401. if ( !ck_krb5_is_installed() )
  9402. return(-1);
  9403. retval = krb5_init_context(&kcontext);
  9404. if (retval) {
  9405. debug(F101,"ck_krb5_get_tkts while initializing krb5","",retval);
  9406. return(-1);
  9407. }
  9408. code = k5_get_ccache(kcontext,&cache,cc_name);
  9409. if (code != 0) {
  9410. debug(F111,"ck_krb5_get_tkts while getting ccache",
  9411. error_message(code),code);
  9412. tkt_count = -1;
  9413. goto exit_k5_get_tkt;
  9414. }
  9415. flags = 0; /* turns off OPENCLOSE mode */
  9416. if ((code = krb5_cc_set_flags(kcontext, cache, flags))) {
  9417. if (code == ENOENT) {
  9418. debug(F111,"ck_krb5_get_tkts (ticket cache)",
  9419. krb5_cc_get_name(kcontext, cache),code);
  9420. } else {
  9421. debug(F111,
  9422. "ck_krb5_get_tkts while setting cache flags (ticket cache)",
  9423. krb5_cc_get_name(kcontext, cache),code);
  9424. }
  9425. tkt_count = -1;
  9426. goto exit_k5_get_tkt;
  9427. }
  9428. if ((code = krb5_cc_get_principal(kcontext, cache, &princ))) {
  9429. debug(F101,"ck_krb5_get_tkts while retrieving principal name",
  9430. "",code);
  9431. tkt_count = -1;
  9432. goto exit_k5_get_tkt;
  9433. }
  9434. if ((code = krb5_unparse_name(kcontext, princ, &defname))) {
  9435. debug(F101,"ck_krb5_get_tkts while unparsing principal name",
  9436. "",code);
  9437. tkt_count = -1;
  9438. goto exit_k5_get_tkt;
  9439. }
  9440. if ((code = krb5_cc_start_seq_get(kcontext, cache, &cur))) {
  9441. debug(F101,"ck_krb5_get_tkts while starting to retrieve tickets",
  9442. "",code);
  9443. tkt_count = -1;
  9444. goto exit_k5_get_tkt;
  9445. }
  9446. while (!(code = krb5_cc_next_cred(kcontext, cache, &cur, &creds))) {
  9447. char *sname=NULL;
  9448. retval = krb5_unparse_name(kcontext, creds.server, &sname);
  9449. if (retval) {
  9450. debug(F101,
  9451. "ck_krb5_get_tkts while unparsing server name","",retval);
  9452. tkt_count = -1;
  9453. goto exit_k5_get_tkt;
  9454. }
  9455. *list = (struct tkt_list_item *) malloc(sizeof(struct tkt_list_item));
  9456. (*list)->name = sname;
  9457. (*list)->next = NULL;
  9458. list = &((*list)->next);
  9459. krb5_free_unparsed_name(kcontext,sname);
  9460. krb5_free_cred_contents(kcontext, &creds);
  9461. tkt_count++;
  9462. }
  9463. if (code == KRB5_CC_END) {
  9464. if ((code = krb5_cc_end_seq_get(kcontext, cache, &cur))) {
  9465. debug(F101,"ck_krb5_get_tkts while finishing ticket retrieval",
  9466. "",code);
  9467. tkt_count = -1;
  9468. goto exit_k5_get_tkt;
  9469. }
  9470. flags = KRB5_TC_OPENCLOSE; /* turns on OPENCLOSE mode */
  9471. if ((code = krb5_cc_set_flags(kcontext, cache, flags))) {
  9472. debug(F101,"ck_krb5_get_tkts while closing ccache",
  9473. "",code);
  9474. tkt_count = -1;
  9475. goto exit_k5_get_tkt;
  9476. }
  9477. } else {
  9478. debug(F101,"ck_krb5_get_tkts while retrieving a ticket","",code);
  9479. tkt_count = -1;
  9480. goto exit_k5_get_tkt;
  9481. }
  9482. exit_k5_get_tkt:
  9483. krb5_free_principal(kcontext,princ);
  9484. krb5_free_unparsed_name(kcontext,defname);
  9485. krb5_cc_close(kcontext,cache);
  9486. krb5_free_context(kcontext);
  9487. return(tkt_count);
  9488. #else /* HEIMDAL */
  9489. return(-1);
  9490. #endif /* HEIMDAL */
  9491. #else /* KRB5 */
  9492. return(0);
  9493. #endif /* KRB5 */
  9494. }
  9495. char *
  9496. #ifdef CK_ANSIC
  9497. ck_krb5_get_next_tkt(VOID)
  9498. #else
  9499. ck_krb5_get_next_tkt()
  9500. #endif
  9501. {
  9502. #ifdef KRB5
  9503. #ifndef HEIMDAL
  9504. static char * s=NULL;
  9505. struct tkt_list_item * next=NULL;
  9506. if ( s ) {
  9507. free(s);
  9508. s = NULL;
  9509. }
  9510. if ( k5_tkt_list == NULL )
  9511. return(NULL);
  9512. next = k5_tkt_list->next;
  9513. s = k5_tkt_list->name;
  9514. free(k5_tkt_list);
  9515. k5_tkt_list = next;
  9516. return(s);
  9517. #else /* HEIMDAL */
  9518. return("Not implemented");
  9519. #endif /* HEIMDAL */
  9520. #else /* KRB5 */
  9521. return(NULL);
  9522. #endif /* KRB5 */
  9523. }
  9524. char *
  9525. #ifdef CK_ANSIC
  9526. ck_krb5_tkt_flags(char * cc_name, char * tktname)
  9527. #else
  9528. ck_krb5_tkt_flags(cc_name,tktname) char * cc_name; char * tktname;
  9529. #endif
  9530. {
  9531. #ifdef KRB5
  9532. #ifndef HEIMDAL
  9533. krb5_context kcontext;
  9534. krb5_error_code retval;
  9535. krb5_ccache cache = NULL;
  9536. krb5_cc_cursor cur;
  9537. krb5_creds creds;
  9538. krb5_principal princ=NULL;
  9539. krb5_flags flags=0;
  9540. krb5_error_code code=0;
  9541. char * flag_str = "";
  9542. if ( !ck_krb5_is_installed() )
  9543. return("");
  9544. retval = krb5_init_context(&kcontext);
  9545. if (retval) {
  9546. debug(F101,"ck_krb5_tkt_flags while initializing krb5","",retval);
  9547. return("");
  9548. }
  9549. code = k5_get_ccache(kcontext,&cache,cc_name);
  9550. if (code != 0) {
  9551. debug(F111,"ck_krb5_tkt_isvalid while getting ccache",
  9552. error_message(code),code);
  9553. goto exit_k5_get_tkt;
  9554. }
  9555. flags = 0; /* turns off OPENCLOSE mode */
  9556. if ((code = krb5_cc_set_flags(kcontext, cache, flags))) {
  9557. if (code == ENOENT) {
  9558. debug(F111,"ck_krb5_tkt_flags (ticket cache)",
  9559. krb5_cc_get_name(kcontext, cache),code);
  9560. } else {
  9561. debug(F111,
  9562. "ck_krb5_tkt_flags while setting cache flags (ticket cache)",
  9563. krb5_cc_get_name(kcontext, cache),code);
  9564. }
  9565. retval = -1;
  9566. goto exit_k5_get_tkt;
  9567. }
  9568. if ((code = krb5_cc_get_principal(kcontext, cache, &princ))) {
  9569. debug(F101,"ck_krb5_tkt_flags while retrieving principal name",
  9570. "",code);
  9571. retval = -1;
  9572. goto exit_k5_get_tkt;
  9573. }
  9574. if ((code = krb5_unparse_name(kcontext, princ, &defname))) {
  9575. debug(F101,"ck_krb5_tkt_flags while unparsing principal name",
  9576. "",code);
  9577. retval = -1;
  9578. goto exit_k5_get_tkt;
  9579. }
  9580. if ((code = krb5_cc_start_seq_get(kcontext, cache, &cur))) {
  9581. debug(F101,"ck_krb5_tkt_flags while starting to retrieve tickets",
  9582. "",code);
  9583. retval = -1;
  9584. goto exit_k5_get_tkt;
  9585. }
  9586. if ((code = krb5_timeofday(kcontext, &now))) {
  9587. if (!status_only)
  9588. debug(F101,"ck_krb5_tkt_flags while getting time of day.",
  9589. "",code);
  9590. retval = -1;
  9591. goto exit_k5_get_tkt;
  9592. }
  9593. while (!(code = krb5_cc_next_cred(kcontext, cache, &cur, &creds))) {
  9594. char *sname=NULL;
  9595. retval = krb5_unparse_name(kcontext, creds.server, &sname);
  9596. if (retval) {
  9597. debug(F101,
  9598. "ck_krb5_tkt_flags while unparsing server name","",retval);
  9599. retval = -1;
  9600. krb5_free_cred_contents(kcontext, &creds);
  9601. goto exit_k5_get_tkt;
  9602. }
  9603. if ( !strcmp(sname,tktname) ) {
  9604. /* we found the ticket we are looking for */
  9605. flag_str = flags_string(&creds);
  9606. krb5_free_unparsed_name(kcontext,sname);
  9607. krb5_free_cred_contents(kcontext, &creds);
  9608. code = KRB5_CC_END;
  9609. break;
  9610. }
  9611. krb5_free_unparsed_name(kcontext,sname);
  9612. krb5_free_cred_contents(kcontext, &creds);
  9613. }
  9614. if (code == KRB5_CC_END) {
  9615. if ((code = krb5_cc_end_seq_get(kcontext, cache, &cur))) {
  9616. debug(F101,"ck_krb5_tkt_flags while finishing ticket retrieval",
  9617. "",code);
  9618. goto exit_k5_get_tkt;
  9619. }
  9620. flags = KRB5_TC_OPENCLOSE; /* turns on OPENCLOSE mode */
  9621. if ((code = krb5_cc_set_flags(kcontext, cache, flags))) {
  9622. debug(F101,"ck_krb5_tkt_flags while closing ccache",
  9623. "",code);
  9624. goto exit_k5_get_tkt;
  9625. }
  9626. } else {
  9627. debug(F101,"ck_krb5_tkt_flags while retrieving a ticket","",code);
  9628. goto exit_k5_get_tkt;
  9629. }
  9630. exit_k5_get_tkt:
  9631. krb5_free_principal(kcontext,princ);
  9632. krb5_free_unparsed_name(kcontext,defname);
  9633. krb5_cc_close(kcontext,cache);
  9634. krb5_free_context(kcontext);
  9635. return(flag_str);
  9636. #else /* HEIMDAL */
  9637. return("Not implemented");
  9638. #endif /* HEIMDAL */
  9639. #else /* KRB5 */
  9640. return("");
  9641. #endif /* KRB5 */
  9642. }
  9643. int
  9644. #ifdef CK_ANSIC
  9645. ck_krb5_tkt_isvalid(char * cc_name, char * tktname)
  9646. #else
  9647. ck_krb5_tkt_isvalid(cc_name,tktname) char * cc_name; char * tktname;
  9648. #endif
  9649. {
  9650. #ifdef KRB5
  9651. #ifndef HEIMDAL
  9652. krb5_context kcontext=NULL;
  9653. krb5_error_code retval;
  9654. krb5_ccache cache = NULL;
  9655. krb5_cc_cursor cur;
  9656. krb5_creds creds;
  9657. krb5_principal princ=NULL;
  9658. krb5_flags flags=0;
  9659. krb5_error_code code=0;
  9660. #ifdef CHECKADDRS
  9661. krb5_address ** myAddrs=NULL;
  9662. krb5_address ** p=NULL;
  9663. BOOL Addrfound = FALSE;
  9664. #endif /*CHECKADDRS*/
  9665. if ( !ck_krb5_is_installed() )
  9666. return(-1);
  9667. retval = krb5_init_context(&kcontext);
  9668. if (retval) {
  9669. debug(F101,"ck_krb5_tkt_isvalid while initializing krb5","",retval);
  9670. return(-1);
  9671. }
  9672. code = k5_get_ccache(kcontext,&cache,cc_name);
  9673. if (code != 0) {
  9674. debug(F111,"ck_krb5_tkt_isvalid while getting ccache",
  9675. error_message(code),code);
  9676. goto exit_k5_get_tkt;
  9677. }
  9678. flags = 0; /* turns off OPENCLOSE mode */
  9679. if ((code = krb5_cc_set_flags(kcontext, cache, flags))) {
  9680. if (code == ENOENT) {
  9681. debug(F111,"ck_krb5_tkt_isvalid (ticket cache)",
  9682. krb5_cc_get_name(kcontext, cache),code);
  9683. } else {
  9684. debug(F111,
  9685. "ck_krb5_tkt_isvalid while setting cache flags (ticket cache)",
  9686. krb5_cc_get_name(kcontext, cache),code);
  9687. }
  9688. retval = -1;
  9689. goto exit_k5_get_tkt;
  9690. }
  9691. if ((code = krb5_cc_get_principal(kcontext, cache, &princ))) {
  9692. debug(F101,"ck_krb5_tkt_isvalid while retrieving principal name",
  9693. "",code);
  9694. retval = -1;
  9695. goto exit_k5_get_tkt;
  9696. }
  9697. if ((code = krb5_unparse_name(kcontext, princ, &defname))) {
  9698. debug(F101,"ck_krb5_tkt_isvalid while unparsing principal name",
  9699. "",code);
  9700. retval = -1;
  9701. goto exit_k5_get_tkt;
  9702. }
  9703. if ((code = krb5_cc_start_seq_get(kcontext, cache, &cur))) {
  9704. debug(F101,"ck_krb5_tkt_isvalid while starting to retrieve tickets",
  9705. "",code);
  9706. retval = -1;
  9707. goto exit_k5_get_tkt;
  9708. }
  9709. if ((code = krb5_timeofday(kcontext, &now))) {
  9710. if (!status_only)
  9711. debug(F101,"ck_krb5_tkt_isvalid while getting time of day.",
  9712. "",code);
  9713. retval = -1;
  9714. goto exit_k5_get_tkt;
  9715. }
  9716. while (!(code = krb5_cc_next_cred(kcontext, cache, &cur, &creds))) {
  9717. char *sname=NULL;
  9718. retval = krb5_unparse_name(kcontext, creds.server, &sname);
  9719. if (retval) {
  9720. debug(F101,
  9721. "ck_krb5_tkt_isvalid while unparsing server name","",retval);
  9722. retval = -1;
  9723. krb5_free_cred_contents(kcontext, &creds);
  9724. goto exit_k5_get_tkt;
  9725. }
  9726. if ( !strcmp(sname,tktname) ) {
  9727. /* we found the ticket we are looking for */
  9728. /* We add a 5 minutes fudge factor to compensate for potential */
  9729. /* clock skew errors between the KDC and K95's host OS */
  9730. retval = ((creds.times.starttime > 0) &&
  9731. now >= (creds.times.starttime - 300) &&
  9732. now < (creds.times.endtime + 300) &&
  9733. !(creds.ticket_flags & TKT_FLG_INVALID));
  9734. #ifdef CHECKADDRS
  9735. if ( retval && krb5_checkaddrs &&
  9736. creds.addresses && creds.addresses[0] ) {
  9737. /* if we think it is valid, then lets check the IP Addresses */
  9738. /* to make sure it is valid for our current connection. */
  9739. /* Also make sure it's for the correct IP address */
  9740. retval = krb5_os_localaddr(kcontext, &myAddrs);
  9741. if (retval) {
  9742. com_err(NULL, retval, "retrieving my IP address");
  9743. krb5_free_unparsed_name(kcontext,sname);
  9744. krb5_free_cred_contents(kcontext, &creds);
  9745. code = KRB5_CC_END;
  9746. retval = -1;
  9747. break;
  9748. }
  9749. /* See if any of our addresses match any in cached credentials */
  9750. for (Addrfound=FALSE, p=myAddrs;
  9751. (Addrfound==FALSE) && (*p);
  9752. p++
  9753. ) {
  9754. if (krb5_address_search(kcontext, *p, creds.addresses)) {
  9755. Addrfound = TRUE;
  9756. }
  9757. }
  9758. krb5_free_addresses(k5_context, myAddrs);
  9759. if (Addrfound) {
  9760. krb5_free_unparsed_name(kcontext,sname);
  9761. krb5_free_cred_contents(kcontext, &creds);
  9762. code = KRB5_CC_END;
  9763. retval = 1;
  9764. break;
  9765. } else {
  9766. krb5_free_unparsed_name(kcontext,sname);
  9767. krb5_free_cred_contents(kcontext, &creds);
  9768. code = KRB5_CC_END;
  9769. retval = 0;
  9770. break;
  9771. }
  9772. }
  9773. #endif /* CHECKADDRS */
  9774. krb5_free_unparsed_name(kcontext,sname);
  9775. krb5_free_cred_contents(kcontext, &creds);
  9776. code = KRB5_CC_END;
  9777. break;
  9778. }
  9779. krb5_free_unparsed_name(kcontext,sname);
  9780. krb5_free_cred_contents(kcontext, &creds);
  9781. }
  9782. if (code == KRB5_CC_END) {
  9783. if ((code = krb5_cc_end_seq_get(kcontext, cache, &cur))) {
  9784. debug(F101,"ck_krb5_tkt_isvalid while finishing ticket retrieval",
  9785. "",code);
  9786. retval = -1;
  9787. goto exit_k5_get_tkt;
  9788. }
  9789. flags = KRB5_TC_OPENCLOSE; /* turns on OPENCLOSE mode */
  9790. if ((code = krb5_cc_set_flags(kcontext, cache, flags))) {
  9791. debug(F101,"ck_krb5_tkt_isvalid while closing ccache",
  9792. "",code);
  9793. retval = -1;
  9794. goto exit_k5_get_tkt;
  9795. }
  9796. } else {
  9797. debug(F101,"ck_krb5_tkt_isvalid while retrieving a ticket","",code);
  9798. retval = -1;
  9799. goto exit_k5_get_tkt;
  9800. }
  9801. exit_k5_get_tkt:
  9802. krb5_free_principal(kcontext,princ);
  9803. krb5_free_unparsed_name(kcontext,defname);
  9804. krb5_cc_close(kcontext,cache);
  9805. krb5_free_context(kcontext);
  9806. return(retval);
  9807. #else /* HEIMDAL */
  9808. return(-1);
  9809. #endif /* HEIMDAL */
  9810. #else /* KRB5 */
  9811. return(-1);
  9812. #endif /* KRB5 */
  9813. }
  9814. int
  9815. #ifdef CK_ANSIC
  9816. ck_krb5_is_tgt_valid(VOID)
  9817. #else
  9818. ck_krb5_is_tgt_valid()
  9819. #endif
  9820. {
  9821. #ifdef KRB5
  9822. #ifndef HEIMDAL
  9823. char tgt[256];
  9824. char * s;
  9825. int rc = 0;
  9826. s = ck_krb5_getrealm(krb5_d_cc);
  9827. ckmakmsg(tgt,sizeof(tgt),"krbtgt/",s,"@",s);
  9828. rc = ck_krb5_tkt_isvalid(krb5_d_cc,tgt);
  9829. debug(F111,"ck_krb5_is_tgt_valid",tgt,rc);
  9830. return(rc>0);
  9831. #else /* HEIMDAL */
  9832. return(-1);
  9833. #endif /* HEIMDAL */
  9834. #else /* KRB5 */
  9835. return(0);
  9836. #endif /* KRB5 */
  9837. }
  9838. int
  9839. #ifdef CK_ANSIC
  9840. ck_krb5_tkt_time(char * cc_name, char * tktname)
  9841. #else
  9842. ck_krb5_tkt_time(cc_name, tktname) char * cc_name; char * tktname;
  9843. #endif
  9844. {
  9845. #ifdef KRB5
  9846. #ifndef HEIMDAL
  9847. krb5_context kcontext;
  9848. krb5_error_code retval;
  9849. krb5_ccache cache = NULL;
  9850. krb5_cc_cursor cur;
  9851. krb5_creds creds;
  9852. krb5_principal princ=NULL;
  9853. krb5_flags flags=0;
  9854. krb5_error_code code=0;
  9855. if ( !ck_krb5_is_installed() )
  9856. return(-1);
  9857. retval = krb5_init_context(&kcontext);
  9858. if (retval) {
  9859. debug(F101,"ck_krb5_list_creds while initializing krb5","",retval);
  9860. return(-1);
  9861. }
  9862. code = k5_get_ccache(kcontext,&cache,cc_name);
  9863. if (code != 0) {
  9864. debug(F111,"ck_krb5_tkt_time while getting ccache",
  9865. error_message(code),code);
  9866. retval = -1;
  9867. goto exit_k5_get_tkt;
  9868. }
  9869. flags = 0; /* turns off OPENCLOSE mode */
  9870. if ((code = krb5_cc_set_flags(kcontext, cache, flags))) {
  9871. if (code == ENOENT) {
  9872. debug(F111,"ck_krb5_list_creds (ticket cache)",
  9873. krb5_cc_get_name(kcontext, cache),code);
  9874. } else {
  9875. debug(F111,
  9876. "ck_krb5_list_creds while setting cache flags (ticket cache)",
  9877. krb5_cc_get_name(kcontext, cache),code);
  9878. }
  9879. retval = -1;
  9880. goto exit_k5_get_tkt;
  9881. }
  9882. if ((code = krb5_cc_get_principal(kcontext, cache, &princ))) {
  9883. debug(F101,"ck_krb5_list_creds while retrieving principal name",
  9884. "",code);
  9885. retval = -1;
  9886. goto exit_k5_get_tkt;
  9887. }
  9888. if ((code = krb5_unparse_name(kcontext, princ, &defname))) {
  9889. debug(F101,"ck_krb5_list_creds while unparsing principal name",
  9890. "",code);
  9891. retval = -1;
  9892. goto exit_k5_get_tkt;
  9893. }
  9894. if ((code = krb5_cc_start_seq_get(kcontext, cache, &cur))) {
  9895. debug(F101,"ck_krb5_list_creds while starting to retrieve tickets",
  9896. "",code);
  9897. retval = -1;
  9898. goto exit_k5_get_tkt;
  9899. }
  9900. if ((code = krb5_timeofday(kcontext, &now))) {
  9901. if (!status_only)
  9902. debug(F101,"ck_krb5_list_creds while getting time of day.",
  9903. "",code);
  9904. krb5_free_context(kcontext);
  9905. return(-1);
  9906. }
  9907. while (!(code = krb5_cc_next_cred(kcontext, cache, &cur, &creds))) {
  9908. char *sname=NULL;
  9909. retval = krb5_unparse_name(kcontext, creds.server, &sname);
  9910. if (retval) {
  9911. debug(F101,
  9912. "ck_krb5_list_creds while unparsing server name","",retval);
  9913. retval = -1;
  9914. krb5_free_unparsed_name(kcontext,sname);
  9915. krb5_free_cred_contents(kcontext, &creds);
  9916. goto exit_k5_get_tkt;
  9917. }
  9918. if ( !strcmp(sname,tktname) ) {
  9919. /* we found the ticket we are looking for */
  9920. int valid = (creds.times.starttime &&
  9921. now > creds.times.starttime &&
  9922. now < creds.times.endtime &&
  9923. !(creds.ticket_flags & TKT_FLG_INVALID));
  9924. if ( valid ) {
  9925. retval = creds.times.endtime - now;
  9926. }
  9927. else
  9928. retval = 0;
  9929. krb5_free_unparsed_name(kcontext,sname);
  9930. krb5_free_cred_contents(kcontext, &creds);
  9931. code = KRB5_CC_END;
  9932. break;
  9933. }
  9934. krb5_free_unparsed_name(kcontext,sname);
  9935. krb5_free_cred_contents(kcontext, &creds);
  9936. }
  9937. if (code == KRB5_CC_END) {
  9938. if ((code = krb5_cc_end_seq_get(kcontext, cache, &cur))) {
  9939. debug(F101,"ck_krb5_list_creds while finishing ticket retrieval",
  9940. "",code);
  9941. retval = -1;
  9942. goto exit_k5_get_tkt;
  9943. }
  9944. flags = KRB5_TC_OPENCLOSE; /* turns on OPENCLOSE mode */
  9945. if ((code = krb5_cc_set_flags(kcontext, cache, flags))) {
  9946. debug(F101,"ck_krb5_list_creds while closing ccache",
  9947. "",code);
  9948. retval = -1;
  9949. goto exit_k5_get_tkt;
  9950. }
  9951. } else {
  9952. debug(F101,"ck_krb5_list_creds while retrieving a ticket","",code);
  9953. retval = -1;
  9954. goto exit_k5_get_tkt;
  9955. }
  9956. exit_k5_get_tkt:
  9957. krb5_free_principal(kcontext,princ);
  9958. krb5_free_unparsed_name(kcontext,defname);
  9959. krb5_cc_close(kcontext,cache);
  9960. krb5_free_context(kcontext);
  9961. return(retval);
  9962. #else /* HEIMDAL */
  9963. return(-1);
  9964. #endif /* HEIMDAL */
  9965. #else /* KRB5 */
  9966. return(-1);
  9967. #endif /* KRB5 */
  9968. }
  9969. char *
  9970. #ifdef CK_ANSIC
  9971. ck_krb5_get_cc_name(void)
  9972. #else
  9973. ck_krb5_get_cc_name()
  9974. #endif
  9975. {
  9976. #ifdef KRB5
  9977. #ifndef HEIMDAL
  9978. static char cc_name[CKMAXPATH+1]="";
  9979. krb5_context kcontext = NULL;
  9980. krb5_ccache ccache = NULL;
  9981. krb5_error_code code;
  9982. char * p=NULL;
  9983. cc_name[0] = '\0';
  9984. if ( !ck_krb5_is_installed() )
  9985. return(cc_name);
  9986. p = getenv("KRB5CCNAME");
  9987. if ( !p ) {
  9988. code = krb5_init_context(&kcontext);
  9989. if (code) {
  9990. com_err("ck_krb5_get_cc_name",code,"while init_context");
  9991. return(cc_name);
  9992. }
  9993. if ((code = krb5_cc_default(kcontext, &ccache))) {
  9994. com_err("ck_krb5_get_cc_name",code,"while getting default ccache");
  9995. goto exit_k5_get_cc;
  9996. }
  9997. ckmakmsg(cc_name,sizeof(cc_name),
  9998. (char *)krb5_cc_get_type(kcontext,ccache),":",
  9999. (char *)krb5_cc_get_name(kcontext,ccache),NULL);
  10000. } else {
  10001. ckstrncpy(cc_name,p,CKMAXPATH);
  10002. }
  10003. if ( !strncmp("FILE:",cc_name,5) ) {
  10004. for ( p=cc_name; *p ; p++ )
  10005. if ( *p == '\\' ) *p = '/';
  10006. }
  10007. exit_k5_get_cc:
  10008. if ( ccache )
  10009. krb5_cc_close(kcontext,ccache);
  10010. if ( kcontext )
  10011. krb5_free_context(kcontext);
  10012. return(cc_name);
  10013. #else /* HEIMDAL */
  10014. return("Not implemented");
  10015. #endif /* HEIMDAL */
  10016. #else /* KRB5 */
  10017. return("");
  10018. #endif /* KRB5 */
  10019. }
  10020. char *
  10021. #ifdef CK_ANSIC
  10022. ck_krb5_getrealm(char * cc_name)
  10023. #else
  10024. ck_krb5_getrealm(cc_name) char * cc_name;
  10025. #endif
  10026. {
  10027. #ifdef KRB5
  10028. #ifndef HEIMDAL
  10029. static char realm[256]="";
  10030. krb5_context kcontext;
  10031. krb5_ccache ccache = NULL;
  10032. krb5_error_code code;
  10033. krb5_principal me=NULL;
  10034. realm[0] = '\0';
  10035. if ( !ck_krb5_is_installed() )
  10036. return(realm);
  10037. code = krb5_init_context(&kcontext);
  10038. if (code) {
  10039. return(realm);
  10040. }
  10041. code = k5_get_ccache(kcontext,&ccache,cc_name);
  10042. if (code != 0) {
  10043. goto exit_k5_getrealm;
  10044. }
  10045. code = krb5_cc_get_principal(kcontext, ccache, &me);
  10046. if (code)
  10047. code = krb5_parse_name(kcontext, "foo", &me);
  10048. if (code) {
  10049. goto exit_k5_getrealm;
  10050. }
  10051. if ( krb5_princ_realm(kcontext, me)->length < sizeof(realm) ) {
  10052. memcpy(realm,krb5_princ_realm(kcontext, me)->data,
  10053. krb5_princ_realm(kcontext, me)->length); /* safe */
  10054. realm[krb5_princ_realm(kcontext, me)->length]='\0';
  10055. }
  10056. exit_k5_getrealm:
  10057. if ( me )
  10058. krb5_free_principal(kcontext,me);
  10059. if ( ccache )
  10060. krb5_cc_close(kcontext,ccache);
  10061. if (kcontext)
  10062. krb5_free_context(kcontext);
  10063. return(realm);
  10064. #else /* HEIMDAL */
  10065. return("Not implemented");
  10066. #endif /* HEIMDAL */
  10067. #else /* KRB5 */
  10068. return("");
  10069. #endif /* KRB5 */
  10070. }
  10071. char *
  10072. #ifdef CK_ANSIC
  10073. ck_krb5_getprincipal(char * cc_name)
  10074. #else
  10075. ck_krb5_getprincipal(cc_name) char * cc_name;
  10076. #endif
  10077. {
  10078. #ifdef KRB5
  10079. #ifndef HEIMDAL
  10080. static char principal[UIDBUFLEN+1]="";
  10081. krb5_context kcontext;
  10082. krb5_ccache ccache = NULL;
  10083. krb5_error_code code;
  10084. krb5_principal me;
  10085. char * p=NULL;
  10086. int i;
  10087. principal[0] = '\0';
  10088. if ( !ck_krb5_is_installed() )
  10089. return(principal);
  10090. code = krb5_init_context(&kcontext);
  10091. if (code) {
  10092. return(principal);
  10093. }
  10094. code = k5_get_ccache(kcontext,&ccache,cc_name);
  10095. if (code != 0) {
  10096. goto exit_k5_getprincipal;
  10097. }
  10098. if ((code = krb5_cc_get_principal(kcontext, ccache, &me))) {
  10099. goto exit_k5_getprincipal;
  10100. }
  10101. if ((code = krb5_unparse_name (kcontext, me, &p))) {
  10102. krb5_free_principal(kcontext,me);
  10103. goto exit_k5_getprincipal;
  10104. }
  10105. ckstrncpy(principal,p,UIDBUFLEN);
  10106. i = ckindex("@",principal,0,0,0);
  10107. if (i)
  10108. principal[i-1] = '\0';
  10109. krb5_free_unparsed_name(kcontext,p);
  10110. exit_k5_getprincipal:
  10111. if ( ccache )
  10112. krb5_cc_close(kcontext,ccache);
  10113. if (kcontext)
  10114. krb5_free_context(kcontext);
  10115. return(principal);
  10116. #else /* HEIMDAL */
  10117. return("Not implemented");
  10118. #endif /* HEIMDAL */
  10119. #else /* KRB5 */
  10120. return("");
  10121. #endif /* KRB5 */
  10122. }
  10123. #ifndef CRYPT_DLL
  10124. int
  10125. ck_get_crypt_table(struct keytab ** pTable, int * pN)
  10126. {
  10127. #ifdef CK_ENCRYPTION
  10128. return(get_crypt_table(pTable, pN));
  10129. #else /* ENCRYPTION */
  10130. int i=0;
  10131. #ifndef OS2
  10132. char * tmpstring = NULL;
  10133. #endif /* OS2 */
  10134. if ( *pTable )
  10135. {
  10136. for ( i=0 ; i < *pN ; i++ )
  10137. free( (*pTable)[i].kwd ) ;
  10138. free ( *pTable ) ;
  10139. }
  10140. *pTable = NULL;
  10141. *pN = 0;
  10142. *pTable = malloc( sizeof(struct keytab) * 2 ) ;
  10143. if ( !(*pTable) )
  10144. return(0);
  10145. #ifdef OS2
  10146. (*pTable)[0].kwd =strdup("automatic");
  10147. #else /* OS2 */
  10148. makestr(&tmpstring,"automatic");
  10149. (*pTable)[0].kwd = tmpstring;
  10150. tmpstring = NULL;
  10151. #endif /* OS2 */
  10152. (*pTable)[0].kwval = ENCTYPE_ANY;
  10153. (*pTable)[0].flgs = 0;
  10154. #ifdef OS2
  10155. (*pTable)[1].kwd =strdup("none");
  10156. #else /* OS2 */
  10157. makestr(&tmpstring,"none");
  10158. (*pTable)[1].kwd = tmpstring;
  10159. tmpstring = NULL;
  10160. #endif /* OS2 */
  10161. (*pTable)[1].kwval = 999;
  10162. (*pTable)[1].flgs = 0;
  10163. (*pN) = 2;
  10164. return(2);
  10165. #endif /* ENCRYPTION */
  10166. }
  10167. VOID
  10168. ck_encrypt_send_support()
  10169. {
  10170. #ifdef CK_ENCRYPTION
  10171. encrypt_send_support();
  10172. #endif /* ENCRYPTION */
  10173. }
  10174. #endif /* CRYPT_DLL */
  10175. /*
  10176. *
  10177. * Kstream
  10178. *
  10179. * Emulates the kstream package in Kerberos 4
  10180. *
  10181. */
  10182. int
  10183. kstream_destroy()
  10184. {
  10185. if (g_kstream != NULL) {
  10186. auth_destroy(); /* Destroy authorizing */
  10187. free(g_kstream);
  10188. g_kstream=NULL;
  10189. }
  10190. return 0;
  10191. }
  10192. VOID
  10193. #ifdef CK_ANSIC
  10194. kstream_set_buffer_mode(int mode)
  10195. #else
  10196. kstream_set_buffer_mode(mode) int mode;
  10197. #endif
  10198. {
  10199. }
  10200. int
  10201. #ifdef CK_ANSIC
  10202. kstream_create_from_fd(int fd,
  10203. kstream_ptr data)
  10204. #else
  10205. kstream_create_from_fd(fd,data)
  10206. int fd; kstream_ptr data;
  10207. #endif
  10208. {
  10209. int n;
  10210. g_kstream = malloc(sizeof(struct kstream_int));
  10211. if (g_kstream == NULL)
  10212. return 0;
  10213. g_kstream->fd = fd;
  10214. n = auth_init(g_kstream); /* Initialize authorizing */
  10215. if (n) {
  10216. free(g_kstream);
  10217. g_kstream = NULL;
  10218. return 0;
  10219. }
  10220. g_kstream->encrypt = NULL;
  10221. g_kstream->decrypt = NULL;
  10222. g_kstream->encrypt_type = ENCTYPE_ANY;
  10223. g_kstream->decrypt_type = ENCTYPE_ANY;
  10224. return 1;
  10225. }
  10226. #ifdef CK_KERBEROS
  10227. #ifdef RLOGCODE
  10228. static int do_lencheck, use_ivecs;
  10229. extern int rlog_inband;
  10230. #ifdef KRB5
  10231. void
  10232. rcmd_stream_init_krb5(in_keyblock, encrypt_flag, lencheck, am_client,
  10233. protonum)
  10234. krb5_keyblock *in_keyblock;
  10235. int encrypt_flag;
  10236. int lencheck;
  10237. int am_client;
  10238. enum krb5_kcmd_proto protonum;
  10239. {
  10240. krb5_error_code status;
  10241. size_t blocksize;
  10242. if (!encrypt_flag)
  10243. return;
  10244. desinbuf.data = des_inbuf;
  10245. desoutbuf.data = des_outpkt+4; /* Set up des buffers */
  10246. k5_session_key = in_keyblock;
  10247. do_lencheck = lencheck;
  10248. if ( protonum == KCMD_OLD_PROTOCOL ) {
  10249. use_ivecs = 0;
  10250. return;
  10251. }
  10252. use_ivecs = 1;
  10253. if (status = krb5_c_block_size(k5_context, k5_session_key->enctype,
  10254. &blocksize)) {
  10255. /* XXX what do I do? */
  10256. printf("fatal kerberos 5 crypto library error\n");
  10257. ttclos(0);
  10258. return;
  10259. }
  10260. encivec_i[0].length = encivec_i[1].length =
  10261. encivec_o[0].length = encivec_o[1].length = blocksize;
  10262. if ((encivec_i[0].data = malloc(encivec_i[0].length * 4)) == NULL) {
  10263. /* XXX what do I do? */
  10264. printf("fatal malloc failed\n");
  10265. ttclos(0);
  10266. return;
  10267. }
  10268. encivec_i[1].data = encivec_i[0].data + encivec_i[0].length;
  10269. encivec_o[0].data = encivec_i[1].data + encivec_i[1].length;
  10270. encivec_o[1].data = encivec_o[0].data + encivec_o[0].length;
  10271. /* is there a better way to initialize this? */
  10272. memset(encivec_i[0].data, am_client, blocksize);
  10273. memset(encivec_o[0].data, 1 - am_client, blocksize);
  10274. memset(encivec_i[1].data, 2 | am_client, blocksize);
  10275. memset(encivec_o[1].data, 2 | (1 - am_client), blocksize);
  10276. }
  10277. #endif /* KRB5 */
  10278. int
  10279. #ifdef CK_ANSIC
  10280. ck_krb_rlogin(CHAR * hostname, int port,
  10281. CHAR * localuser, CHAR * remoteuser, CHAR * term_speed,
  10282. struct sockaddr_in * l_addr, struct sockaddr_in * r_addr,
  10283. int kversion, int encrypt_flag)
  10284. #else /* CK_ANSIC */
  10285. ck_krb_rlogin(hostname, port,
  10286. localuser, remoteuser, term_speed, l_addr, r_addr, encrypt_flag)
  10287. CHAR * hostname; int port;
  10288. CHAR * localuser; CHAR * remoteuser; CHAR * term_speed;
  10289. struct sockaddr_in * l_addr; struct sockaddr_in * r_addr;
  10290. int kversion; int encrypt_flag;
  10291. #endif /* CK_ANSIC */
  10292. {
  10293. unsigned long status;
  10294. char * realm=NULL;
  10295. extern int ttyfd;
  10296. int c;
  10297. long msglen;
  10298. debug(F111,"ck_krb_rlogin",hostname,port);
  10299. if ( kversion == 4 && !ck_krb4_is_installed() ) {
  10300. printf("?Kerberos 4 is not installed\r\n");
  10301. return(-1);
  10302. } else if ( kversion == 5 && !ck_krb5_is_installed() ) {
  10303. printf("?Kerberos 5 is not installed\r\n");
  10304. return(-1);
  10305. }
  10306. if ( encrypt_flag && !ck_crypt_is_installed() ) {
  10307. printf("?Encryption is not installed\r\n");
  10308. return(-1);
  10309. }
  10310. if ( kversion == 5 ) {
  10311. #ifdef KRB5
  10312. krb5_flags authopts=0;
  10313. krb5_ccache ccache=NULL;
  10314. char *cksumbuf=NULL;
  10315. char *service=NULL;
  10316. char * kcmd_version=NULL;
  10317. enum krb5_kcmd_proto use_proto;
  10318. krb5_data cksumdat;
  10319. krb5_creds *get_cred = 0;
  10320. krb5_error_code status;
  10321. krb5_error *error = 0;
  10322. krb5_ap_rep_enc_part *rep_ret = NULL;
  10323. krb5_data outbuf;
  10324. int rc;
  10325. krb5_int32 seqno=0;
  10326. krb5_int32 server_seqno=0;
  10327. char ** realmlist=NULL;
  10328. int buflen;
  10329. char tgt[256];
  10330. debug(F100,"ck_krb_rlogin version 5","",0);
  10331. realm = ck_krb5_realmofhost((char *)hostname);
  10332. if (!realm) {
  10333. ckstrncpy(strTmp, "Can't find realm for host \"",AUTHTMPBL);
  10334. ckstrncat(strTmp, (char *)hostname,AUTHTMPBL);
  10335. ckstrncat(strTmp, "\"",AUTHTMPBL);
  10336. printf("?Kerberos 5 error: %s\r\n",strTmp);
  10337. krb5_errno = KRB5_ERR_HOST_REALM_UNKNOWN;
  10338. makestr(&krb5_errmsg,strTmp);
  10339. return(0);
  10340. }
  10341. ckmakmsg(tgt,sizeof(tgt),"krbtgt/",realm,"@",realm);
  10342. debug(F110,"ck_rlog_rlogin TGT",tgt,0);
  10343. if ( krb5_autoget &&
  10344. !((ck_krb5_tkt_isvalid(NULL,tgt) > 0) ||
  10345. (ck_krb5_is_tgt_valid() > 0)) )
  10346. ck_krb5_autoget_TGT(realm);
  10347. buflen = strlen((char *)term_speed) + strlen((char *)remoteuser) + 64;
  10348. if ((cksumbuf = malloc(buflen)) == 0) {
  10349. printf("Unable to allocate memory for checksum buffer.\r\n");
  10350. return(-1);
  10351. }
  10352. ckmakmsg(cksumbuf,buflen,ckuitoa((unsigned short) ntohs(port)),":",
  10353. (char *)term_speed,(char *)remoteuser);
  10354. cksumdat.data = cksumbuf;
  10355. cksumdat.length = strlen(cksumbuf);
  10356. status = krb5_init_context(&k5_context);
  10357. if (status) {
  10358. debug(F110,"ck_krb_rlogin()","unable to init_context",0);
  10359. return(-1);
  10360. }
  10361. desinbuf.data = des_inbuf;
  10362. desoutbuf.data = des_outpkt+4; /* Set up des buffers */
  10363. rc = k5_get_ccache(k5_context,&ccache,NULL);
  10364. if (rc != 0) {
  10365. com_err(NULL, rc, "while getting ccache.");
  10366. return(0);
  10367. }
  10368. service = krb5_d_srv ? krb5_d_srv : KRB5_SERVICE_NAME;
  10369. if (!(get_cred = (krb5_creds *)calloc(1, sizeof(krb5_creds)))) {
  10370. printf("ck_krb_rlogin: no memory\r\n");
  10371. return(-1);
  10372. }
  10373. memset(get_cred,0,sizeof(krb5_creds));
  10374. status = krb5_sname_to_principal(k5_context, (char *) hostname,
  10375. service, KRB5_NT_SRV_HST,
  10376. &get_cred->server);
  10377. if (status) {
  10378. printf("ck_krb_rlogin: krb5_sname_to_principal failed: %s\r\n",
  10379. error_message(status));
  10380. return(-1);
  10381. }
  10382. ttoc(0);
  10383. if (status = krb5_cc_get_principal(k5_context,
  10384. ccache,
  10385. &get_cred->client)
  10386. ) {
  10387. (void) krb5_cc_close(k5_context, ccache);
  10388. krb5_free_creds(k5_context, get_cred);
  10389. goto bad;
  10390. }
  10391. if (krb5_rlog_ver == KCMD_OLD_PROTOCOL)
  10392. get_cred->keyblock.enctype=ENCTYPE_DES_CBC_CRC;
  10393. /* Get ticket from credentials cache or kdc */
  10394. status = krb5_get_credentials(k5_context,
  10395. 0,
  10396. ccache,
  10397. get_cred,
  10398. &ret_cred
  10399. );
  10400. krb5_free_creds(k5_context, get_cred);
  10401. get_cred = NULL;
  10402. (void) krb5_cc_close(k5_context, ccache);
  10403. if (status)
  10404. goto bad;
  10405. /* Reset internal flags; these should not be set. */
  10406. authopts &= (~OPTS_FORWARD_CREDS);
  10407. authopts &= (~OPTS_FORWARDABLE_CREDS);
  10408. if (krb5_auth_con_init(k5_context, &auth_context))
  10409. goto bad;
  10410. if (krb5_auth_con_setflags(k5_context, auth_context,
  10411. KRB5_AUTH_CONTEXT_RET_TIME))
  10412. goto bad;
  10413. /* Only need local address for mk_cred() to send to krlogind */
  10414. if (!krb5_d_no_addresses)
  10415. if (status = krb5_auth_con_genaddrs(k5_context,
  10416. auth_context,
  10417. ttyfd,
  10418. KRB5_AUTH_CONTEXT_GENERATE_LOCAL_FULL_ADDR
  10419. ))
  10420. goto bad;
  10421. /* Here is where we start to handle the new protocol in earnest */
  10422. if ( krb5_rlog_ver == KCMD_PROTOCOL_COMPAT_HACK ) {
  10423. krb5_boolean is_des;
  10424. if (status = krb5_c_enctype_compare( k5_context,
  10425. ENCTYPE_DES_CBC_CRC,
  10426. #ifdef HEIMDAL
  10427. ret_cred->session.keytype,
  10428. #else /* HEIMDAL */
  10429. ret_cred->keyblock.enctype,
  10430. #endif /* HEIMDAL */
  10431. &is_des)) {
  10432. krb5_free_creds(k5_context, ret_cred);
  10433. ret_cred = NULL;
  10434. goto bad;
  10435. }
  10436. if ( is_des ) {
  10437. kcmd_version = "KCMDV0.1";
  10438. use_proto = KCMD_OLD_PROTOCOL;
  10439. } else {
  10440. authopts = AP_OPTS_USE_SUBKEY;
  10441. kcmd_version = "KCMDV0.2";
  10442. use_proto = KCMD_NEW_PROTOCOL;
  10443. }
  10444. } else {
  10445. use_proto = krb5_rlog_ver;
  10446. switch ( krb5_rlog_ver ) {
  10447. case KCMD_NEW_PROTOCOL:
  10448. authopts = AP_OPTS_USE_SUBKEY;
  10449. kcmd_version = "KCMDV0.2";
  10450. break;
  10451. case KCMD_OLD_PROTOCOL:
  10452. kcmd_version = "KCMDV0.1";
  10453. break;
  10454. default:
  10455. goto bad;
  10456. }
  10457. }
  10458. /* call Kerberos library routine to obtain an authenticator,
  10459. pass it over the socket to the server, and obtain mutual
  10460. authentication.
  10461. */
  10462. status = krb5_sendauth(k5_context,
  10463. &auth_context,
  10464. (krb5_pointer) &ttyfd,
  10465. kcmd_version,
  10466. ret_cred->client,
  10467. ret_cred->server,
  10468. authopts,
  10469. &cksumdat,
  10470. ret_cred,
  10471. 0,
  10472. &error,
  10473. &rep_ret,
  10474. NULL
  10475. );
  10476. krb5_free_data_contents(k5_context,&cksumdat);
  10477. if (status) {
  10478. if ( !quiet )
  10479. printf("Couldn't authenticate to server: %s\r\n",
  10480. error_message(status));
  10481. if (error) {
  10482. if ( !quiet ) {
  10483. printf("Server returned error code %d (%s)\r\n",
  10484. error->error,
  10485. error_message(ERROR_TABLE_BASE_krb5 + error->error));
  10486. if (error->text.length) {
  10487. printf("Error text sent from server: %s\r\n",
  10488. error->text.data);
  10489. }
  10490. }
  10491. krb5_free_error(k5_context, error);
  10492. error = 0;
  10493. }
  10494. goto bad;
  10495. }
  10496. if (rep_ret) {
  10497. server_seqno = rep_ret->seq_number;
  10498. krb5_free_ap_rep_enc_part(k5_context, rep_ret);
  10499. }
  10500. (void) ttol(remoteuser, strlen((char *)remoteuser)+1);
  10501. (void) ttol(term_speed, strlen((char *)term_speed)+1);
  10502. (void) ttol(localuser, strlen((char *)localuser)+1);
  10503. if (forward_flag) { /* Forward credentials (global) */
  10504. if (status = krb5_fwd_tgt_creds( k5_context,
  10505. auth_context,
  10506. (char *)hostname,
  10507. ret_cred->client,
  10508. ret_cred->server,
  10509. 0,
  10510. (forwardable_flag ?
  10511. OPTS_FORWARDABLE_CREDS :
  10512. 0),
  10513. &outbuf
  10514. )
  10515. )
  10516. {
  10517. printf("Error forwarding credentials: %s\r\n",
  10518. error_message(status));
  10519. goto bad2;
  10520. }
  10521. /* Send forwarded credentials */
  10522. status = krb5_write_message(k5_context,
  10523. (krb5_pointer)&ttyfd,
  10524. &outbuf
  10525. );
  10526. }
  10527. else { /* Dummy write to signal no forwarding */
  10528. bad2:
  10529. outbuf.length = 0;
  10530. status = krb5_write_message(k5_context,
  10531. (krb5_pointer)&ttyfd,
  10532. &outbuf);
  10533. }
  10534. if ((c = ttinc(0)) < 0) {
  10535. if (c==-1) {
  10536. perror((char *)hostname);
  10537. } else {
  10538. printf("ck_krb_rlogin: bad connection with remote host\r\n");
  10539. }
  10540. status = -1;
  10541. goto bad;
  10542. }
  10543. if (c != 0) {
  10544. while ((c = ttinc(1)) >= 0) {
  10545. (void) printf("%c",c);
  10546. if (c == '\n')
  10547. break;
  10548. }
  10549. status = -1;
  10550. goto bad;
  10551. }
  10552. if ( status == 0 ) { /* success */
  10553. krb5_keyblock * key = 0;
  10554. if ( use_proto == KCMD_NEW_PROTOCOL ) {
  10555. int on = 1;
  10556. rlog_inband = 1;
  10557. setsockopt(ttyfd, SOL_SOCKET, SO_OOBINLINE,
  10558. (char *) &on, sizeof on);
  10559. status = krb5_auth_con_getlocalsubkey( k5_context,
  10560. auth_context,
  10561. &key);
  10562. if ((status || !key) && encrypt_flag )
  10563. goto bad2;
  10564. }
  10565. if ( key == 0 ) {
  10566. #ifdef HEIMDAL
  10567. key = &ret_cred->session;
  10568. #else /* HEIMDAL */
  10569. key = &ret_cred->keyblock;
  10570. #endif /* HEIMDAL */
  10571. }
  10572. rcmd_stream_init_krb5(key, encrypt_flag, 1, 1, use_proto);
  10573. if ( encrypt_flag )
  10574. rlog_encrypt = 1;
  10575. }
  10576. return (0); /* success */
  10577. bad:
  10578. if ( status && !quiet ) {
  10579. printf("Kerberos authentication error: %s\r\n",
  10580. error_message(status));
  10581. }
  10582. if (ret_cred) {
  10583. krb5_free_creds(k5_context, ret_cred);
  10584. ret_cred = NULL;
  10585. }
  10586. return (status);
  10587. #else /* KRB5 */
  10588. return(-1);
  10589. #endif /* KRB5 */
  10590. } else if (kversion == 4) {
  10591. #ifdef KRB4
  10592. char tgt[4*REALM_SZ+1];
  10593. debug(F100,"ck_krb_rlogin version 4","",0);
  10594. realm = (char *)krb_realmofhost(hostname);
  10595. if (!realm) {
  10596. strcpy(strTmp, "Can't find realm for host \"");
  10597. ckstrncat(strTmp, hostname,AUTHTMPBL);
  10598. ckstrncat(strTmp, "\"",AUTHTMPBL);
  10599. printf("?Kerberos 4 error: %s\r\n",strTmp);
  10600. krb4_errno = 0;
  10601. makestr(&krb4_errmsg,strTmp);
  10602. return(0);
  10603. }
  10604. ckmakmsg(tgt,sizeof(tgt),"krbtgt.",realm,"@",realm);
  10605. status = ck_krb4_tkt_isvalid(tgt);
  10606. if ( status <= 0 && krb4_autoget )
  10607. ck_krb4_autoget_TGT(realm);
  10608. ttoc(0); /* write a NUL */
  10609. status = krb_sendauth(encrypt_flag?KOPT_DO_MUTUAL:0,
  10610. ttyfd,
  10611. &k4_auth,
  10612. krb4_d_srv ? krb4_d_srv : KRB4_SERVICE_NAME,
  10613. hostname,
  10614. realm,
  10615. (unsigned long) getpid(),
  10616. &k4_msg_data,
  10617. &cred,
  10618. #ifdef CK_ENCRYPTION
  10619. &k4_sched,
  10620. #else /* ENCRYPTION */
  10621. NULL,
  10622. #endif /* ENCRYPTION */
  10623. l_addr,
  10624. r_addr,
  10625. "KCMDV0.1");
  10626. debug(F111,"ck_krb_rlogin","krb_sendauth",status);
  10627. if (status != KSUCCESS) {
  10628. printf( "krb_sendauth failed: %s\r\n",
  10629. krb_get_err_text_entry(status)
  10630. );
  10631. return(-1);
  10632. }
  10633. ttol(remoteuser,strlen(remoteuser)+1);
  10634. ttol(term_speed,strlen(term_speed)+1);
  10635. reread:
  10636. if ((c = ttinc(0)) < 0) {
  10637. printf("rcmd: bad connection with remote host\r\n");
  10638. return(-1);
  10639. }
  10640. debug(F111,"ck_krb_rlogin","first byte",c);
  10641. if (c != 0) {
  10642. char *check = "ld.so: warning:";
  10643. /* If rlogind was compiled on SunOS4, and it somehow
  10644. got the shared library version numbers wrong, it
  10645. may give an ld.so warning about an old version of a
  10646. shared library. Just ignore any such warning.
  10647. Note that the warning is a characteristic of the
  10648. server; we may not ourselves be running under
  10649. SunOS4. */
  10650. if (c == 'l') {
  10651. char *p;
  10652. char cc;
  10653. p = &check[1];
  10654. while ((c = ttinc(0)) >= 0) {
  10655. if (*p == '\0') {
  10656. if (c == '\n')
  10657. break;
  10658. } else {
  10659. if (c != *p)
  10660. break;
  10661. ++p;
  10662. }
  10663. }
  10664. if (*p == '\0')
  10665. goto reread;
  10666. }
  10667. printf(check);
  10668. while ((c = ttinc(1)) >= 0) {
  10669. printf("%c",c);
  10670. if (c == '\n')
  10671. break;
  10672. }
  10673. debug(F110,"ck_krb_rlogin","fatal error 1",0);
  10674. return(-1);
  10675. }
  10676. #ifdef CK_ENCRYPTION
  10677. if ( encrypt_flag ) {
  10678. /* if we are encrypting we need to setup the encryption */
  10679. /* routines. */
  10680. des_key_sched(cred.session, k4_sched);
  10681. rlog_encrypt = 1;
  10682. }
  10683. #endif /* ENCRYPTION */
  10684. #else /* KRB4 */
  10685. return(-1);
  10686. #endif /* KRB4 */
  10687. }
  10688. return(0); /* success */
  10689. }
  10690. #define SRAND srand
  10691. #define RAND rand
  10692. #define RAND_TYPE int
  10693. static long
  10694. random_confounder(size, fillin)
  10695. size_t size;
  10696. char * fillin;
  10697. {
  10698. static int seeded = 0;
  10699. register unsigned char *real_fill;
  10700. RAND_TYPE rval;
  10701. if (!seeded) {
  10702. /* time() defined in 4.12.2.4, but returns a time_t, which is an
  10703. "arithmetic type" (4.12.1) */
  10704. rval = (RAND_TYPE) time(0);
  10705. SRAND(rval);
  10706. rval = RAND();
  10707. rval ^= getpid();
  10708. SRAND(rval);
  10709. seeded = 1;
  10710. }
  10711. real_fill = (unsigned char *)fillin;
  10712. while (size > 0) {
  10713. rval = RAND();
  10714. *real_fill = rval & 0xff;
  10715. real_fill++;
  10716. size--;
  10717. if (size) {
  10718. *real_fill = (rval >> 8) & 0xff;
  10719. real_fill++;
  10720. size--;
  10721. }
  10722. }
  10723. return 0;
  10724. }
  10725. #ifdef KRB5
  10726. int
  10727. krb5_des_avail(fd)
  10728. int fd;
  10729. {
  10730. return(nstored);
  10731. }
  10732. int
  10733. krb5_des_read(fd, buf, len, secondary)
  10734. int fd;
  10735. register char *buf;
  10736. int len;
  10737. int secondary;
  10738. {
  10739. int nreturned = 0;
  10740. long net_len,rd_len;
  10741. int cc;
  10742. krb5_error_code status;
  10743. unsigned char c;
  10744. krb5_data plain;
  10745. krb5_enc_data cipher;
  10746. debug(F111,"krb5_des_read","len",len);
  10747. debug(F111,"krb5_des_read","rlog_encrypt",rlog_encrypt);
  10748. if ( !rlog_encrypt ) {
  10749. cc = net_read(fd, buf, len);
  10750. debug(F111,"krb5_des_read","chars read",cc);
  10751. if ( cc < 0 )
  10752. netclos();
  10753. return(cc);
  10754. }
  10755. if (nstored >= len) {
  10756. if ( buf ) {
  10757. memcpy(buf, store_ptr, len); /* safe */
  10758. store_ptr += len;
  10759. nstored -= len;
  10760. return(len);
  10761. } else
  10762. return(0);
  10763. } else if (nstored) {
  10764. if ( buf ) {
  10765. memcpy(buf, store_ptr, nstored); /* safe */
  10766. nreturned += nstored;
  10767. buf += nstored;
  10768. len -= nstored;
  10769. nstored = 0;
  10770. }
  10771. else
  10772. return(0);
  10773. }
  10774. /* See the comment in v4_des_read. */
  10775. while (1) {
  10776. cc = net_read(fd, &c, 1);
  10777. /* we should check for non-blocking here, but we'd have
  10778. to make it save partial reads as well. */
  10779. if (cc <= 0) {
  10780. return cc; /* read error */
  10781. }
  10782. if (cc == 1) {
  10783. if (c == 0 || !do_lencheck)
  10784. break;
  10785. }
  10786. }
  10787. rd_len = c;
  10788. if ((cc = net_read(fd, &c, 1)) != 1) return 0;
  10789. rd_len = (rd_len << 8) | c;
  10790. if ((cc = net_read(fd, &c, 1)) != 1) return 0;
  10791. rd_len = (rd_len << 8) | c;
  10792. if ((cc = net_read(fd, &c, 1)) != 1) return 0;
  10793. rd_len = (rd_len << 8) | c;
  10794. if (status = krb5_c_encrypt_length(k5_context,
  10795. k5_session_key->enctype,
  10796. use_ivecs ? rd_len + 4 : rd_len,
  10797. (size_t *)&net_len)) {
  10798. errno = status;
  10799. return(-1);
  10800. }
  10801. if ((net_len <= 0) || (net_len > sizeof(des_inbuf))) {
  10802. /* preposterous length; assume out-of-sync; only
  10803. recourse is to close connection, so return 0 */
  10804. printf("Read size problem.\r\n");
  10805. return(0);
  10806. }
  10807. if ((cc = net_read(fd, desinbuf.data, net_len)) != net_len )
  10808. {
  10809. /* pipe must have closed, return 0 */
  10810. printf( "Read error: length received %d != expected %d.\r\n",
  10811. cc,
  10812. net_len
  10813. );
  10814. return(cc);
  10815. }
  10816. /* decrypt info */
  10817. cipher.enctype = ENCTYPE_UNKNOWN;
  10818. cipher.ciphertext.length = net_len;
  10819. cipher.ciphertext.data = desinbuf.data;
  10820. plain.length = sizeof(storage);
  10821. plain.data = storage;
  10822. if ( status = krb5_c_decrypt(k5_context, k5_session_key, KCMD_KEYUSAGE,
  10823. use_ivecs ? encivec_i + secondary : 0,
  10824. &cipher,&plain) ) {
  10825. /* probably out of sync */
  10826. printf("Cannot decrypt data from network: %s\r\n",
  10827. error_message(status));
  10828. errno = EIO;
  10829. return(-1);
  10830. }
  10831. store_ptr = storage;
  10832. nstored = rd_len;
  10833. if ( use_ivecs ) {
  10834. int rd_len2;
  10835. rd_len2 = storage[0] & 0xff;
  10836. rd_len2 <<= 8; rd_len2 |= storage[1] & 0xff;
  10837. rd_len2 <<= 8; rd_len2 |= storage[2] & 0xff;
  10838. rd_len2 <<= 8; rd_len2 |= storage[3] & 0xff;
  10839. if (rd_len2 != rd_len) {
  10840. /* cleartext length trashed? */
  10841. errno = EIO;
  10842. return -1;
  10843. }
  10844. store_ptr += 4;
  10845. }
  10846. if ( !buf )
  10847. return(0);
  10848. #ifdef RLOGCODE /* blah */
  10849. if (rlog_inband && (ttnproto == NP_K5LOGIN || ttnproto == NP_EK5LOGIN))
  10850. {
  10851. int i, left, n;
  10852. for (i = 0; i < nstored; i++) {
  10853. if (store_ptr[i] == '\377' &&
  10854. store_ptr[i+1] == '\377') {
  10855. left = nstored - i;
  10856. n = rlog_ctrl(&store_ptr[i], left);
  10857. if (n < 0) {
  10858. left -= (-n);
  10859. nstored = left;
  10860. /* flush before, and (-n) bytes */
  10861. if (left > 0)
  10862. memmove(store_ptr, &store_ptr[i-n], left);
  10863. } else if (n) {
  10864. left -= n;
  10865. nstored -= n;
  10866. if (left > 0)
  10867. memmove(store_ptr, &store_ptr[n], left);
  10868. }
  10869. }
  10870. }
  10871. }
  10872. #endif /* RLOGCODE */
  10873. if (nstored > len) {
  10874. memcpy(buf, store_ptr, len); /* safe */
  10875. nreturned += len;
  10876. store_ptr += len;
  10877. nstored -= len;
  10878. } else {
  10879. memcpy(buf, store_ptr, nstored); /* safe */
  10880. nreturned += nstored;
  10881. nstored = 0;
  10882. }
  10883. return(nreturned);
  10884. }
  10885. int
  10886. krb5_des_write(fd, buf, len, secondary)
  10887. int fd;
  10888. char *buf;
  10889. int len;
  10890. int secondary;
  10891. {
  10892. char tmpbuf[2*RLOG_BUFSIZ+8];
  10893. unsigned char *len_buf = (unsigned char *) tmpbuf;
  10894. krb5_error_code status;
  10895. krb5_data plain;
  10896. krb5_enc_data cipher;
  10897. debug(F111,"krb5_des_write","rlog_encrypt",rlog_encrypt);
  10898. if ( !rlog_encrypt ) {
  10899. int cc = net_write(fd, buf, len);
  10900. debug(F111,"net_write","chars written",cc);
  10901. return(cc != len ? -1 : len);
  10902. }
  10903. if (use_ivecs) {
  10904. unsigned char *lenbuf2 = (unsigned char *) tmpbuf;
  10905. if (len + 4 > sizeof(tmpbuf))
  10906. abort ();
  10907. lenbuf2[0] = (len & 0xff000000) >> 24;
  10908. lenbuf2[1] = (len & 0xff0000) >> 16;
  10909. lenbuf2[2] = (len & 0xff00) >> 8;
  10910. lenbuf2[3] = (len & 0xff);
  10911. memcpy (tmpbuf + 4, buf, len);
  10912. plain.data = tmpbuf;
  10913. plain.length = len + 4;
  10914. } else {
  10915. plain.data = buf;
  10916. plain.length = len;
  10917. }
  10918. cipher.ciphertext.length = sizeof(des_outpkt)-4;
  10919. cipher.ciphertext.data = desoutbuf.data;
  10920. if ( status = krb5_c_encrypt(k5_context, k5_session_key, KCMD_KEYUSAGE,
  10921. use_ivecs ? encivec_o + secondary : 0,
  10922. &plain, &cipher)) {
  10923. printf("Write encrypt problem: %s.\r\n",
  10924. error_message(status));
  10925. errno = EIO;
  10926. return(-1);
  10927. }
  10928. desoutbuf.length = cipher.ciphertext.length;
  10929. len_buf = (unsigned char *) des_outpkt;
  10930. len_buf[0] = (len & 0xff000000) >> 24;
  10931. len_buf[1] = (len & 0xff0000) >> 16;
  10932. len_buf[2] = (len & 0xff00) >> 8;
  10933. len_buf[3] = (len & 0xff);
  10934. if (net_write(fd, des_outpkt,desoutbuf.length+4)
  10935. != desoutbuf.length+4){
  10936. printf("Could not write out all data\r\n");
  10937. return(-1);
  10938. }
  10939. else return(len);
  10940. }
  10941. #endif /* KRB5 */
  10942. #ifdef KRB4
  10943. /*
  10944. * Note that the encrypted rlogin packets take the form of a four-byte
  10945. * length followed by encrypted data. On writing the data out, a significant
  10946. * performance penalty is suffered (at least one RTT per character, two if we
  10947. * are waiting for a shell to echo) by writing the data separately from the
  10948. * length. So, unlike the input buffer, which just contains the output
  10949. * data, the output buffer represents the entire packet.
  10950. */
  10951. int
  10952. krb4_des_avail(fd)
  10953. int fd;
  10954. {
  10955. return(nstored);
  10956. }
  10957. int
  10958. krb4_des_read(fd, buf, len)
  10959. int fd;
  10960. register char *buf;
  10961. int len;
  10962. {
  10963. int nreturned = 0;
  10964. unsigned long net_len, rd_len;
  10965. int cc;
  10966. unsigned char c;
  10967. int gotzero = 0;
  10968. debug(F111,"krb4_des_read","rlog_encrypt",rlog_encrypt);
  10969. debug(F111,"krb4_des_read","len",len);
  10970. if ( !rlog_encrypt ) {
  10971. cc = net_read(fd, buf, len);
  10972. debug(F111,"krb4_des_read","chars read",cc);
  10973. if ( cc < 0 )
  10974. netclos();
  10975. return(cc);
  10976. }
  10977. if (nstored >= len) {
  10978. if ( buf ) {
  10979. debug(F111,"krb4_des_read (nstored >= len)","nstored",nstored);
  10980. memcpy(buf, store_ptr, len); /* safe */
  10981. store_ptr += len;
  10982. nstored -= len;
  10983. return(len);
  10984. } else
  10985. return(0);
  10986. } else if (nstored) {
  10987. if ( buf ) {
  10988. debug(F111,"krb4_des_read (nstored)","nstored",nstored);
  10989. memcpy(buf, store_ptr, nstored); /* safe */
  10990. nreturned += nstored;
  10991. buf += nstored;
  10992. len -= nstored;
  10993. nstored = 0;
  10994. } else
  10995. return(0);
  10996. }
  10997. /* We're fetching the length which is MSB first, and the MSB
  10998. has to be zero unless the client is sending more than 2^24
  10999. (16M) bytes in a single write (which is why this code is in
  11000. rlogin but not rcp or rsh.) The only reasons we'd get something
  11001. other than zero are:
  11002. -- corruption of the tcp stream (which will show up when
  11003. everything else is out of sync too)
  11004. -- un-caught Berkeley-style "pseudo out-of-band data" which
  11005. happens any time the user hits ^C twice.
  11006. The latter is *very* common, as shown by an 'rlogin -x -d'
  11007. using the CNS V4 rlogin. Mark EIchin 1/95
  11008. */
  11009. debug(F110,"krb4_des_read",
  11010. "about to call net_read() this will block",
  11011. 0
  11012. );
  11013. do {
  11014. cc = net_read(fd, &c, 1);
  11015. debug(F111,"net_read","chars read",cc);
  11016. if (cc <= 0) {
  11017. netclos();
  11018. return(-1);
  11019. }
  11020. if (cc != 1) return 0; /* read error */
  11021. if (cc == 1) {
  11022. if (c == 0) gotzero = 1;
  11023. }
  11024. } while (!gotzero);
  11025. debug(F110,"krb4_des_read","gotzero",0);
  11026. cc = net_read(fd, &c, 1);
  11027. debug(F111,"net_read","chars read",cc);
  11028. if (cc < 0) {
  11029. netclos();
  11030. return(-1);
  11031. } else if ( cc != 1 )
  11032. return(0);
  11033. net_len = c;
  11034. cc = net_read(fd, &c, 1);
  11035. debug(F111,"net_read","chars read",cc);
  11036. if (cc < 0) {
  11037. netclos();
  11038. return(-1);
  11039. } else if ( cc != 1 )
  11040. return(0);
  11041. net_len = (net_len << 8) | c;
  11042. debug(F111,"net_read","chars read",cc);
  11043. cc = net_read(fd, &c, 1);
  11044. if (cc < 0) {
  11045. netclos();
  11046. return(-1);
  11047. } else if ( cc != 1 )
  11048. return(0);
  11049. net_len = (net_len << 8) | c;
  11050. debug(F111,"krb4_des_read","net_len",net_len);
  11051. /* Note: net_len is unsigned */
  11052. if (net_len > sizeof(des_inbuf)) {
  11053. /* XXX preposterous length, probably out of sync.
  11054. act as if pipe closed */
  11055. return(0);
  11056. }
  11057. /* the writer tells us how much real data we are getting, but
  11058. we need to read the pad bytes (8-byte boundary) */
  11059. #ifndef roundup
  11060. #define roundup(x,y) ((((x)+(y)-1)/(y))*(y))
  11061. #endif /* roundup */
  11062. rd_len = roundup(net_len, 8);
  11063. debug(F111,"krb4_des_read","rd_len",rd_len);
  11064. cc = net_read(fd, des_inbuf, rd_len);
  11065. debug(F111,"net_read","chars read",cc);
  11066. if (cc < 0) {
  11067. netclos();
  11068. return(-1);
  11069. } else if ( cc != rd_len )
  11070. return(0);
  11071. ckhexdump("krb4_des_read des_inbuf",des_inbuf,8);
  11072. #ifdef CK_ENCRYPTION
  11073. #ifdef KRB524
  11074. (void) des_pcbc_encrypt(des_inbuf,
  11075. storage,
  11076. (net_len < 8) ? 8 : net_len,
  11077. k4_sched,
  11078. cred.session,
  11079. DECRYPT);
  11080. #else /* KRB524 */
  11081. (void) des_pcbc_encrypt((Block *)des_inbuf,
  11082. (Block *)storage,
  11083. (net_len < 8) ? 8 : net_len,
  11084. k4_sched,
  11085. &cred.session,
  11086. DECRYPT);
  11087. #endif /* KRB524 */
  11088. #endif /* ENCRYPTION */
  11089. ckhexdump("krb4_des_read storage",storage,8);
  11090. /*
  11091. * when the cleartext block is < 8 bytes, it is "right-justified"
  11092. * in the block, so we need to adjust the pointer to the data
  11093. */
  11094. if (net_len < 8)
  11095. store_ptr = storage + 8 - net_len;
  11096. else
  11097. store_ptr = storage;
  11098. nstored = net_len;
  11099. if ( !buf )
  11100. return(0);
  11101. if (nstored > len) {
  11102. memcpy(buf, store_ptr, len); /* safe */
  11103. nreturned += len;
  11104. store_ptr += len;
  11105. nstored -= len;
  11106. } else {
  11107. memcpy(buf, store_ptr, nstored); /* safe */
  11108. nreturned += nstored;
  11109. nstored = 0;
  11110. }
  11111. debug(F111,"net_read","nreturned",nreturned);
  11112. return(nreturned);
  11113. }
  11114. int
  11115. krb4_des_write(fd, buf, len)
  11116. int fd;
  11117. char *buf;
  11118. int len;
  11119. {
  11120. static char garbage_buf[8];
  11121. unsigned char *len_buf = (unsigned char *) des_outpkt;
  11122. int cc;
  11123. debug(F111,"krb4_des_write","rlog_encrypt",rlog_encrypt);
  11124. if ( !rlog_encrypt ) {
  11125. cc = net_write(fd, buf, len);
  11126. debug(F111,"net_write","chars written",cc);
  11127. return(cc);
  11128. }
  11129. /*
  11130. * pcbc_encrypt outputs in 8-byte (64 bit) increments
  11131. *
  11132. * it zero-fills the cleartext to 8-byte padding,
  11133. * so if we have cleartext of < 8 bytes, we want
  11134. * to insert random garbage before it so that the ciphertext
  11135. * differs for each transmission of the same cleartext.
  11136. * if len < 8 - sizeof(long), sizeof(long) bytes of random
  11137. * garbage should be sufficient; leave the rest as-is in the buffer.
  11138. * if len > 8 - sizeof(long), just garbage fill the rest.
  11139. */
  11140. if (len < 8) {
  11141. random_confounder(8 - len, garbage_buf);
  11142. /* this "right-justifies" the data in the buffer */
  11143. (void) memcpy(garbage_buf + 8 - len, buf, len); /* safe */
  11144. ckhexdump("krb4_des_write garbage_buf",garbage_buf,8);
  11145. } else
  11146. ckhexdump("krb4_des_write buf",buf,8);
  11147. #ifdef CK_ENCRYPTION
  11148. #ifdef KRB524
  11149. (void) des_pcbc_encrypt((len < 8) ? garbage_buf : buf,
  11150. des_outpkt+4,
  11151. (len < 8) ? 8 : len,
  11152. k4_sched,
  11153. cred.session,
  11154. ENCRYPT);
  11155. #else /* KRB524 */
  11156. (void) des_pcbc_encrypt((Block *)((len < 8) ? garbage_buf : buf),
  11157. (Block *)(des_outpkt+4),
  11158. (len < 8) ? 8 : len,
  11159. k4_sched,
  11160. &cred.session,
  11161. ENCRYPT);
  11162. #endif /* KRB524 */
  11163. #endif /* ENCRYPTION */
  11164. if ( len < 8 )
  11165. ckhexdump("krb4_des_write (post pcbc) garbage_buf",garbage_buf,8);
  11166. else
  11167. ckhexdump("krb4_des_write (post pcbc) buf",buf,8);
  11168. ckhexdump("krb4_des_write (des_outpkt+4)",(des_outpkt+4),8);
  11169. /* tell the other end the real amount, but send an 8-byte padded
  11170. packet */
  11171. len_buf[0] = (len & 0xff000000) >> 24;
  11172. len_buf[1] = (len & 0xff0000) >> 16;
  11173. len_buf[2] = (len & 0xff00) >> 8;
  11174. len_buf[3] = (len & 0xff);
  11175. ckhexdump("krb4_des_write des_outpkt len",des_outpkt,12);
  11176. cc = net_write(fd, des_outpkt, roundup(len,8)+4);
  11177. debug(F111,"net_write","chars written",cc);
  11178. return(len);
  11179. }
  11180. #endif /* KRB4 */
  11181. #endif /* RLOGCODE */
  11182. #ifdef KRB524
  11183. #ifndef OS2
  11184. /* The following functions are missing from the compatibility library */
  11185. const char *
  11186. krb_get_err_text_entry(r) int r;
  11187. {
  11188. extern char krb_err_text[];
  11189. return(krb_err_txt[r]);
  11190. }
  11191. #endif /* OS2 */
  11192. #endif /* KRB524 */
  11193. #endif /* CK_KERBEROS */
  11194. #ifdef CK_KERBEROS
  11195. #ifdef KRB5_U2U
  11196. /* Kerberos 5 User to User Client */
  11197. int
  11198. k5_user_to_user_client_auth()
  11199. {
  11200. extern int ttyfd;
  11201. register int retval, i;
  11202. char **srealms; /* realm(s) of server */
  11203. char *princ; /* principal in credentials cache */
  11204. krb5_ccache cc;
  11205. krb5_creds creds, *new_creds;
  11206. krb5_data reply, msg, msgtext, princ_data;
  11207. krb5_ticket * ticket = NULL;
  11208. if (retval = k5_get_ccache(k5_context,&cc,NULL))
  11209. {
  11210. com_err("uu-client", retval, "getting credentials cache");
  11211. return(-1);
  11212. }
  11213. memset ((char*)&creds, 0, sizeof(creds));
  11214. if (retval = krb5_cc_get_principal(k5_context, cc, &creds.client))
  11215. {
  11216. com_err("uu-client", retval, "getting principal name");
  11217. return(-1);
  11218. }
  11219. if (retval = krb5_get_host_realm(k5_context, szHostName, &srealms))
  11220. {
  11221. com_err("uu-client", retval, "getting realms for \"%s\"", szHostName);
  11222. return(-1);
  11223. }
  11224. if (retval = krb5_build_principal_ext(k5_context, &creds.server,
  11225. krb5_princ_realm(k5_context,
  11226. creds.client)->length,
  11227. krb5_princ_realm(k5_context,
  11228. creds.client)->data,
  11229. 6, "krbtgt",
  11230. krb5_princ_realm(k5_context,
  11231. creds.client)->length,
  11232. krb5_princ_realm(k5_context,
  11233. creds.client)->data,
  11234. 0))
  11235. {
  11236. com_err("uu-client", retval, "setting up tgt server name");
  11237. return(-1);
  11238. }
  11239. /* Get TGT from credentials cache */
  11240. if (retval = krb5_get_credentials(k5_context, KRB5_GC_CACHED, cc,
  11241. &creds, &new_creds))
  11242. {
  11243. com_err("uu-client", retval, "getting TGT");
  11244. return(-1);
  11245. }
  11246. if (retval = krb5_unparse_name(k5_context, creds.client, &princ)) {
  11247. com_err("uu-client", retval, "printing principal name");
  11248. return(-1);
  11249. }
  11250. i = strlen(princ) + 1;
  11251. princ_data.data = princ;
  11252. princ_data.length = i; /* include null terminator for
  11253. server's convenience */
  11254. retval = krb5_write_message(k5_context,
  11255. (krb5_pointer) &ttyfd, &princ_data);
  11256. if (retval)
  11257. {
  11258. com_err("uu-client", retval, "sending principal name to server");
  11259. return(-1);
  11260. }
  11261. krb5_free_unparsed_name(k5_context,princ);
  11262. retval = krb5_write_message(k5_context,
  11263. (krb5_pointer) &ttyfd, &new_creds->ticket);
  11264. if (retval)
  11265. {
  11266. com_err("uu-client", retval, "sending ticket to server");
  11267. return(-1);
  11268. }
  11269. retval = krb5_read_message(k5_context, (krb5_pointer) &ttyfd, &reply);
  11270. if (retval)
  11271. {
  11272. com_err("uu-client", retval, "reading reply from server");
  11273. return(-1);
  11274. }
  11275. if (retval = krb5_auth_con_init(k5_context, &auth_context)) {
  11276. com_err("uu-client", retval, "initializing the auth_context");
  11277. return(-1);
  11278. }
  11279. if (!krb5_d_no_addresses) {
  11280. if (retval = krb5_auth_con_genaddrs(k5_context, auth_context, ttyfd,
  11281. KRB5_AUTH_CONTEXT_GENERATE_LOCAL_FULL_ADDR |
  11282. KRB5_AUTH_CONTEXT_GENERATE_REMOTE_FULL_ADDR)) {
  11283. com_err("uu-client", retval, "generating addrs for auth_context");
  11284. return(-1);
  11285. }
  11286. }
  11287. if (retval = krb5_auth_con_setflags(k5_context, auth_context,
  11288. KRB5_AUTH_CONTEXT_DO_SEQUENCE)) {
  11289. com_err("uu-client", retval, "initializing the auth_context flags");
  11290. return(-1);
  11291. }
  11292. if (retval = krb5_auth_con_setuseruserkey(k5_context, auth_context,
  11293. &new_creds->keyblock)) {
  11294. com_err("uu-client", retval, "setting useruserkey for authcontext");
  11295. return(-1);
  11296. }
  11297. /* read the ap_req to get the session key */
  11298. retval = krb5_rd_req(k5_context, &auth_context, &reply,
  11299. NULL, NULL, NULL, &ticket);
  11300. if (retval) {
  11301. com_err("uu-client", retval, "reading AP_REQ from server");
  11302. return(-1);
  11303. }
  11304. if (k5_u2u_read_msg(k5_context,&msg) < 0)
  11305. return(-1);
  11306. if ( strcmp("Kermit implements Kerberos 5 User to User",msg.data) )
  11307. return(-1);
  11308. krb5_free_data_contents(k5_context,&msg);
  11309. msgtext.data = "As do I! :-)";
  11310. msgtext.length = strlen(msgtext.data)+1;
  11311. if (k5_u2u_write_msg(k5_context,&msgtext) < 0)
  11312. return(-1);
  11313. if (retval = krb5_unparse_name(k5_context,
  11314. #ifdef HEIMDAL
  11315. ticket->client,
  11316. #else /* HEIMDAL */
  11317. ticket->enc_part2->client,
  11318. #endif /* HEIMDAL */
  11319. &princ))
  11320. com_err("uu-client", retval, "while unparsing client name");
  11321. else {
  11322. ckstrncpy(szUserNameAuthenticated,princ,UIDBUFLEN);
  11323. validUser = AUTH_VALID;
  11324. authentication_version = AUTHTYPE_KERBEROS_V5;
  11325. if ( !quiet )
  11326. printf("Peer name is \"%s\"\n", princ);
  11327. krb5_free_unparsed_name(k5_context,princ);
  11328. }
  11329. return 0;
  11330. }
  11331. /* Kerberos 5 User to User Server */
  11332. int
  11333. k5_user_to_user_server_auth()
  11334. {
  11335. krb5_data pname_data, tkt_data;
  11336. int retval;
  11337. krb5_creds creds, *new_creds;
  11338. krb5_ccache cc;
  11339. krb5_data msg, msgtext;
  11340. extern int ttyfd;
  11341. if (retval = krb5_read_message(k5_context,
  11342. (krb5_pointer) &ttyfd, &pname_data)) {
  11343. com_err ("uu-server", retval, "reading pname");
  11344. return(-1);
  11345. }
  11346. /* client sends it already null-terminated. */
  11347. if ( !quiet )
  11348. printf ("Peer name is \"%s\".\n", pname_data.data);
  11349. ckstrncpy(szUserNameAuthenticated,pname_data.data,UIDBUFLEN);
  11350. validUser = AUTH_VALID;
  11351. authentication_version = AUTHTYPE_KERBEROS_V5;
  11352. if (retval = krb5_read_message(k5_context,
  11353. (krb5_pointer) &ttyfd, &tkt_data)) {
  11354. com_err ("uu-server", retval, "reading ticket data");
  11355. return(-1);
  11356. }
  11357. if (retval = k5_get_ccache(k5_context,&cc,NULL))
  11358. {
  11359. com_err("uu-server", retval, "getting credentials cache");
  11360. return(-1);
  11361. }
  11362. memset ((char*)&creds, 0, sizeof(creds));
  11363. if (retval = krb5_cc_get_principal(k5_context, cc, &creds.client))
  11364. {
  11365. com_err("uu-server", retval, "getting principal name");
  11366. return(-1);
  11367. }
  11368. if (retval = krb5_parse_name(k5_context, pname_data.data, &creds.server))
  11369. {
  11370. com_err("uu-server", retval, "parsing client name");
  11371. return(-1);
  11372. }
  11373. creds.second_ticket = tkt_data;
  11374. if (retval = krb5_get_credentials(k5_context, KRB5_GC_USER_USER,
  11375. cc, &creds, &new_creds))
  11376. {
  11377. com_err("uu-server", retval, "getting user-user ticket");
  11378. return(-1);
  11379. }
  11380. /* send a ticket/authenticator to the other side, so it can get the key
  11381. we're using for the krb_safe below. */
  11382. if (retval = krb5_auth_con_init(k5_context, &auth_context)) {
  11383. com_err("uu-server", retval, "making auth_context");
  11384. return(-1);
  11385. }
  11386. if (retval = krb5_auth_con_setflags(k5_context, auth_context,
  11387. KRB5_AUTH_CONTEXT_DO_SEQUENCE)) {
  11388. com_err("uu-server", retval, "initializing the auth_context flags");
  11389. return(-1);
  11390. }
  11391. if (!krb5_d_no_addresses) {
  11392. if (retval = krb5_auth_con_genaddrs(k5_context, auth_context, ttyfd,
  11393. KRB5_AUTH_CONTEXT_GENERATE_LOCAL_FULL_ADDR |
  11394. KRB5_AUTH_CONTEXT_GENERATE_REMOTE_FULL_ADDR)) {
  11395. com_err("uu-server", retval, "generating addrs for auth_context");
  11396. return(-1);
  11397. }
  11398. }
  11399. if (retval = krb5_auth_con_setuseruserkey(k5_context, auth_context,
  11400. &new_creds->keyblock)) {
  11401. com_err("uu-server", retval, "setting useruserkey for authcontext");
  11402. return(-1);
  11403. }
  11404. if (retval = krb5_mk_req_extended(k5_context, &auth_context,
  11405. AP_OPTS_USE_SESSION_KEY |
  11406. AP_OPTS_MUTUAL_REQUIRED,
  11407. NULL, new_creds, &msg)) {
  11408. com_err("uu-server", retval, "making AP_REQ");
  11409. return(-1);
  11410. }
  11411. retval = krb5_write_message(k5_context, (krb5_pointer) &ttyfd, &msg);
  11412. if (retval) {
  11413. com_err("uu-server", retval, "writing message to client");
  11414. return(-1);
  11415. }
  11416. krb5_free_data_contents(k5_context,&msg);
  11417. msgtext.data = "Kermit implements Kerberos 5 User to User";
  11418. msgtext.length = strlen(msgtext.data)+1;
  11419. if (k5_u2u_write_msg(k5_context,&msgtext) < 0)
  11420. return(-1);
  11421. if (k5_u2u_read_msg(k5_context,&msg) < 0)
  11422. return(-1);
  11423. if ( strcmp("As do I! :-)",msg.data) )
  11424. return(-1);
  11425. krb5_free_data_contents(k5_context,&msg);
  11426. return(0);
  11427. }
  11428. int
  11429. k5_u2u_read_msg(krb5_context context, int fd, krb5_data * msg)
  11430. {
  11431. int retval;
  11432. krb5_data reply;
  11433. retval = krb5_read_message(context, (krb5_pointer) &fd, &reply);
  11434. if (retval)
  11435. {
  11436. com_err("uu-client", retval, "reading reply");
  11437. return(-1);
  11438. }
  11439. if (retval = krb5_rd_priv(context, auth_context, &reply, msg, NULL)) {
  11440. com_err("uu-client", retval, "decoding reply");
  11441. return(-1);
  11442. }
  11443. return(0);
  11444. }
  11445. int
  11446. k5_u2u_write_msg(krb5_context context, int fd, krb5_data * msgtext)
  11447. {
  11448. int retval;
  11449. krb5_data msg;
  11450. if (retval = krb5_mk_priv(k5_context, auth_context, msgtext, &msg, NULL))
  11451. {
  11452. com_err("uu-server", retval, "encoding message");
  11453. return(-1);
  11454. }
  11455. retval = krb5_write_message(k5_context, (krb5_pointer) &fd, &msg);
  11456. krb5_free_data_contents(k5_context,&msg);
  11457. if (retval)
  11458. {
  11459. com_err("uu-server", retval, "writing message");
  11460. return(-1);
  11461. }
  11462. return(0);
  11463. }
  11464. int
  11465. krb5_u2u_avail(fd)
  11466. int fd;
  11467. {
  11468. return(nstored);
  11469. }
  11470. int
  11471. krb5_u2u_read(fd, buf, len)
  11472. int fd;
  11473. register char *buf;
  11474. int len;
  11475. {
  11476. int nreturned = 0;
  11477. krb5_data msg;
  11478. debug(F111,"krb5_u2u_read","len",len);
  11479. if ( !buf )
  11480. return(0);
  11481. if (nstored >= len) {
  11482. memcpy(buf, store_ptr, len); /* safe */
  11483. store_ptr += len;
  11484. nstored -= len;
  11485. return(len);
  11486. } else if (nstored) {
  11487. memcpy(buf, store_ptr, nstored); /* safe */
  11488. nreturned += nstored;
  11489. buf += nstored;
  11490. len -= nstored;
  11491. nstored = 0;
  11492. }
  11493. if (k5_u2u_read_msg(k5_context, fd, &msg) < 0)
  11494. return(-1);
  11495. if ( msg.length <= len ) {
  11496. memcpy(buf, msg.data, msg.length);
  11497. nreturned += msg.length;
  11498. nstored = 0;
  11499. } else {
  11500. memcpy(buf, msg.data, len);
  11501. nreturned += len;
  11502. if ( msg.length - len < sizeof(storage) ) {
  11503. store_ptr = storage;
  11504. nstored = msg.length - len;
  11505. memcpy(storage,msg.data+len,nstored);
  11506. } else {
  11507. nstored = 0;
  11508. return(-1);
  11509. }
  11510. }
  11511. return(nreturned);
  11512. }
  11513. int
  11514. krb5_u2u_write(fd, buf, len)
  11515. int fd;
  11516. char *buf;
  11517. int len;
  11518. {
  11519. krb5_data msg;
  11520. msg.length = len;
  11521. msg.data = buf;
  11522. if ( k5_u2u_write_msg(k5_context, fd, &msg) < 0 )
  11523. return(-1);
  11524. else
  11525. return(len);
  11526. }
  11527. #endif /* KRB5_U2U */
  11528. #endif /* CK_KERBEROS */
  11529. #ifdef CK_FORWARD_X
  11530. /*
  11531. Copyright (c) 1988 X Consortium
  11532. Permission is hereby granted, free of charge, to any person obtaining a copy
  11533. of this software and associated documentation files (the "Software"), to deal
  11534. in the Software without restriction, including without limitation the rights
  11535. to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  11536. copies of the Software, and to permit persons to whom the Software is
  11537. furnished to do so, subject to the following conditions:
  11538. The above copyright notice and this permission notice shall be included in
  11539. all copies or substantial portions of the Software.
  11540. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  11541. IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  11542. FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  11543. X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
  11544. AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
  11545. CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  11546. Except as contained in this notice, the name of the X Consortium shall not be
  11547. used in advertising or otherwise to promote the sale, use or other dealings
  11548. in this Software without prior written authorization from the X Consortium.
  11549. */
  11550. /* Modified for stand-alone compiling by
  11551. * Peter 'Luna' Runestig <peter@runestig.com>
  11552. */
  11553. #include <stdlib.h>
  11554. #include <string.h>
  11555. #include <fcntl.h>
  11556. #include <sys/stat.h>
  11557. #include <time.h>
  11558. #define Time_t time_t
  11559. void
  11560. XauDisposeAuth (auth)
  11561. Xauth *auth;
  11562. {
  11563. if (auth) {
  11564. if (auth->address) (void) free (auth->address);
  11565. if (auth->number) (void) free (auth->number);
  11566. if (auth->name) (void) free (auth->name);
  11567. if (auth->data) {
  11568. (void) bzero (auth->data, auth->data_length);
  11569. (void) free (auth->data);
  11570. }
  11571. free ((char *) auth);
  11572. }
  11573. return;
  11574. }
  11575. char *
  11576. XauFileName ()
  11577. {
  11578. char *slashDotXauthority = "/.Xauthority";
  11579. char *name;
  11580. static char *buf=NULL;
  11581. static int bsize=0;
  11582. int size, namelen;
  11583. extern char * tn_fwdx_xauthority;
  11584. if ( tn_fwdx_xauthority )
  11585. return(tn_fwdx_xauthority);
  11586. if (name = getenv ("XAUTHORITY"))
  11587. return(name);
  11588. name = zhome();
  11589. if ( !name )
  11590. return(NULL);
  11591. namelen = strlen (name);
  11592. size = namelen + strlen(slashDotXauthority) + 1;
  11593. if (size > bsize) {
  11594. if (buf)
  11595. free (buf);
  11596. buf = malloc ((unsigned) size);
  11597. if (!buf)
  11598. return 0;
  11599. bsize = size;
  11600. }
  11601. ckstrncpy (buf, name, bsize);
  11602. if ( name[namelen-1] != '/'
  11603. #ifdef OS2
  11604. && name[namelen-1] != '\\'
  11605. #endif /* OS2 */
  11606. )
  11607. ckstrncat (buf, slashDotXauthority, bsize);
  11608. else
  11609. ckstrncat (buf, &slashDotXauthority[1], bsize);
  11610. return(buf);
  11611. }
  11612. static int
  11613. binaryEqual (a, b, len)
  11614. register char *a, *b;
  11615. register int len;
  11616. {
  11617. while (len--)
  11618. if (*a++ != *b++)
  11619. return 0;
  11620. return 1;
  11621. }
  11622. #ifndef R_OK
  11623. #define R_OK 04
  11624. #endif /* R_OK */
  11625. Xauth *
  11626. XauGetAuthByAddr (family, address_length, address,
  11627. number_length, number,
  11628. name_length, name)
  11629. unsigned int family;
  11630. unsigned int address_length;
  11631. const char *address;
  11632. unsigned int number_length;
  11633. const char *number;
  11634. unsigned int name_length;
  11635. const char *name;
  11636. {
  11637. FILE *auth_file;
  11638. char *auth_name;
  11639. Xauth *entry;
  11640. auth_name = XauFileName();
  11641. if (!auth_name)
  11642. return 0;
  11643. if (access (auth_name, R_OK) != 0) /* checks REAL id */
  11644. return 0;
  11645. auth_file = fopen (auth_name, "rb");
  11646. if (!auth_file)
  11647. return 0;
  11648. for (;;) {
  11649. entry = XauReadAuth (auth_file);
  11650. if (!entry)
  11651. break;
  11652. /*
  11653. * Match when:
  11654. * either family or entry->family are FamilyWild or
  11655. * family and entry->family are the same
  11656. * and
  11657. * either address or entry->address are empty or
  11658. * address and entry->address are the same
  11659. * and
  11660. * either number or entry->number are empty or
  11661. * number and entry->number are the same
  11662. * and
  11663. * either name or entry->name are empty or
  11664. * name and entry->name are the same
  11665. */
  11666. /* if ((family == FamilyWild || entry->family == FamilyWild ||
  11667. (entry->family == family &&
  11668. address_length == entry->address_length &&
  11669. binaryEqual (entry->address, address, (int)address_length))) &&
  11670. (number_length == 0 || entry->number_length == 0 ||
  11671. (number_length == entry->number_length &&
  11672. binaryEqual (entry->number, number, (int)number_length))) &&
  11673. (name_length == 0 || entry->name_length == 0 ||
  11674. (entry->name_length == name_length &&
  11675. binaryEqual (entry->name, name, (int)name_length)))) */
  11676. /* the original matching code above doesn't seem to meet the matching
  11677. * algorithm, it doesn't check if "address_length == 0 ||
  11678. * entry->address_length == 0". / Luna 2000-02-09
  11679. */
  11680. if ((family == FamilyWild || entry->family == FamilyWild ||
  11681. entry->family == family) &&
  11682. (address_length == 0 || entry->address_length == 0 ||
  11683. (address_length == entry->address_length &&
  11684. binaryEqual (entry->address, address, (int)address_length))) &&
  11685. (number_length == 0 || entry->number_length == 0 ||
  11686. (number_length == entry->number_length &&
  11687. binaryEqual (entry->number, number, (int)number_length))) &&
  11688. (name_length == 0 || entry->name_length == 0 ||
  11689. (entry->name_length == name_length &&
  11690. binaryEqual (entry->name, name, (int)name_length))))
  11691. break;
  11692. XauDisposeAuth (entry);
  11693. }
  11694. (void) fclose (auth_file);
  11695. return entry;
  11696. }
  11697. static int
  11698. read_short (shortp, file)
  11699. unsigned short *shortp;
  11700. FILE *file;
  11701. {
  11702. unsigned char file_short[2];
  11703. if (fread ((char *) file_short, (int) sizeof (file_short), 1, file) != 1)
  11704. return 0;
  11705. *shortp = file_short[0] * 256 + file_short[1];
  11706. return 1;
  11707. }
  11708. static int
  11709. read_counted_string (countp, stringp, file)
  11710. unsigned short *countp;
  11711. char **stringp;
  11712. FILE *file;
  11713. {
  11714. unsigned short len;
  11715. char *data;
  11716. if (read_short (&len, file) == 0)
  11717. return 0;
  11718. if (len == 0) {
  11719. data = 0;
  11720. } else {
  11721. data = malloc ((unsigned) len);
  11722. if (!data)
  11723. return 0;
  11724. if (fread (data, (int) sizeof (char), (int) len, file) != len) {
  11725. bzero (data, len);
  11726. free (data);
  11727. return 0;
  11728. }
  11729. }
  11730. *stringp = data;
  11731. *countp = len;
  11732. return 1;
  11733. }
  11734. Xauth *
  11735. XauReadAuth (auth_file)
  11736. FILE *auth_file;
  11737. {
  11738. Xauth local;
  11739. Xauth *ret;
  11740. if (read_short (&local.family, auth_file) == 0)
  11741. return 0;
  11742. if (read_counted_string (&local.address_length,
  11743. &local.address, auth_file) == 0)
  11744. return 0;
  11745. if (read_counted_string (&local.number_length,
  11746. &local.number, auth_file) == 0) {
  11747. if (local.address) free (local.address);
  11748. return 0;
  11749. }
  11750. if (read_counted_string (&local.name_length,
  11751. &local.name, auth_file) == 0) {
  11752. if (local.address) free (local.address);
  11753. if (local.number) free (local.number);
  11754. return 0;
  11755. }
  11756. if (read_counted_string (&local.data_length,
  11757. &local.data, auth_file) == 0) {
  11758. if (local.address) free (local.address);
  11759. if (local.number) free (local.number);
  11760. if (local.name) free (local.name);
  11761. return 0;
  11762. }
  11763. ret = (Xauth *) malloc (sizeof (Xauth));
  11764. if (!ret) {
  11765. if (local.address) free (local.address);
  11766. if (local.number) free (local.number);
  11767. if (local.name) free (local.name);
  11768. if (local.data) {
  11769. bzero (local.data, local.data_length);
  11770. free (local.data);
  11771. }
  11772. return 0;
  11773. }
  11774. *ret = local;
  11775. return ret;
  11776. }
  11777. static int
  11778. write_short (s, file)
  11779. unsigned short s;
  11780. FILE *file;
  11781. {
  11782. unsigned char file_short[2];
  11783. file_short[0] = (s & (unsigned)0xff00) >> 8;
  11784. file_short[1] = s & 0xff;
  11785. if (fwrite ((char *) file_short, (int) sizeof (file_short), 1, file) != 1)
  11786. return 0;
  11787. return 1;
  11788. }
  11789. static int
  11790. write_counted_string (count, string, file)
  11791. unsigned short count;
  11792. char *string;
  11793. FILE *file;
  11794. {
  11795. if (write_short (count, file) == 0)
  11796. return 0;
  11797. if (fwrite (string, (int) sizeof (char), (int) count, file) != count)
  11798. return 0;
  11799. return 1;
  11800. }
  11801. int
  11802. XauWriteAuth (auth_file, auth)
  11803. FILE *auth_file;
  11804. Xauth *auth;
  11805. {
  11806. if (write_short (auth->family, auth_file) == 0)
  11807. return 0;
  11808. if (write_counted_string (auth->address_length,
  11809. auth->address, auth_file) == 0)
  11810. return 0;
  11811. if (write_counted_string (auth->number_length,
  11812. auth->number, auth_file) == 0)
  11813. return 0;
  11814. if (write_counted_string (auth->name_length, auth->name, auth_file) == 0)
  11815. return 0;
  11816. if (write_counted_string (auth->data_length, auth->data, auth_file) == 0)
  11817. return 0;
  11818. return 1;
  11819. }
  11820. #ifdef KRB5
  11821. #ifdef K5_XAUTH
  11822. /*
  11823. * functions to encode/decode Kerberos V5 principals
  11824. * into something that can be reasonable spewed over
  11825. * the wire
  11826. *
  11827. * Author: Tom Yu <tlyu@MIT.EDU>
  11828. *
  11829. * Still needs to be fixed up wrt signed/unsigned lengths, but we'll worry
  11830. * about that later.
  11831. */
  11832. /*
  11833. * XauKrb5Encode
  11834. *
  11835. * this function encodes the principal passed to it in a format that can
  11836. * easily be dealt with by stuffing it into an X packet. Encoding is as
  11837. * follows:
  11838. * length count of the realm name
  11839. * realm
  11840. * component count
  11841. * length of component
  11842. * actual principal component
  11843. * etc....
  11844. *
  11845. * Note that this function allocates a hunk of memory, which must be
  11846. * freed to avoid nasty memory leak type things. All counts are
  11847. * byte-swapped if needed. (except for the total length returned)
  11848. *
  11849. * nevermind.... stuffing the encoded packet in net byte order just to
  11850. * always do the right thing. Don't have to frob with alignment that way.
  11851. */
  11852. int
  11853. XauKrb5Encode(princ, outbuf)
  11854. krb5_principal princ; /* principal to encode */
  11855. krb5_data *outbuf; /* output buffer */
  11856. {
  11857. CARD16 i, numparts, totlen = 0, plen, rlen;
  11858. char *cp, *pdata;
  11859. rlen = krb5_princ_realm(princ)->length;
  11860. numparts = krb5_princ_size(princ);
  11861. totlen = 2 + rlen + 2; /* include room for realm length
  11862. and component count */
  11863. for (i = 0; i < numparts; i++)
  11864. totlen += krb5_princ_component(princ, i)->length + 2;
  11865. /* add 2 bytes each time for length */
  11866. if ((outbuf->data = (char *)malloc(totlen)) == NULL)
  11867. return -1;
  11868. cp = outbuf->data;
  11869. *cp++ = (char)((int)(0xff00 & rlen) >> 8);
  11870. *cp++ = (char)(0x00ff & rlen);
  11871. memcpy(cp, krb5_princ_realm(princ)->data, rlen); /* safe */
  11872. cp += rlen;
  11873. *cp++ = (char)((int)(0xff00 & numparts) >> 8);
  11874. *cp++ = (char)(0x00ff & numparts);
  11875. for (i = 0; i < numparts; i++)
  11876. {
  11877. plen = krb5_princ_component(princ, i)->length;
  11878. pdata = krb5_princ_component(princ, i)->data;
  11879. *cp++ = (char)((int)(0xff00 & plen) >> 8);
  11880. *cp++ = (char)(0x00ff & plen);
  11881. memcpy(cp, pdata, plen); /* safe */
  11882. cp += plen;
  11883. }
  11884. outbuf->length = totlen;
  11885. return 0;
  11886. }
  11887. /*
  11888. * XauKrb5Decode
  11889. *
  11890. * This function essentially reverses what XauKrb5Encode does.
  11891. * return value: 0 if okay, -1 if malloc fails, -2 if inbuf format bad
  11892. */
  11893. int
  11894. XauKrb5Decode(inbuf, princ)
  11895. krb5_data inbuf;
  11896. krb5_principal *princ;
  11897. {
  11898. CARD16 i, numparts, plen, rlen;
  11899. CARD8 *cp, *pdata;
  11900. if (inbuf.length < 4)
  11901. {
  11902. return -2;
  11903. }
  11904. *princ = (krb5_principal)malloc(sizeof (krb5_principal_data));
  11905. if (*princ == NULL)
  11906. return -1;
  11907. bzero(*princ, sizeof (krb5_principal_data));
  11908. cp = (CARD8 *)inbuf.data;
  11909. rlen = *cp++ << 8;
  11910. rlen |= *cp++;
  11911. if (inbuf.length < 4 + (int)rlen + 2)
  11912. {
  11913. krb5_free_principal(*princ);
  11914. return -2;
  11915. }
  11916. krb5_princ_realm(*princ)->data = (char *)malloc(rlen);
  11917. if (krb5_princ_realm(*princ)->data == NULL)
  11918. {
  11919. krb5_free_principal(*princ);
  11920. return -1;
  11921. }
  11922. krb5_princ_realm(*princ)->length = rlen;
  11923. memcpy(krb5_princ_realm(*princ)->data, cp, rlen); /* safe */
  11924. cp += rlen;
  11925. numparts = *cp++ << 8;
  11926. numparts |= *cp++;
  11927. krb5_princ_name(*princ) =
  11928. (krb5_data *)malloc(numparts * sizeof (krb5_data));
  11929. if (krb5_princ_name(*princ) == NULL)
  11930. {
  11931. krb5_free_principal(*princ);
  11932. return -1;
  11933. }
  11934. krb5_princ_size(*princ) = 0;
  11935. for (i = 0; i < numparts; i++)
  11936. {
  11937. if (cp + 2 > (CARD8 *)inbuf.data + inbuf.length)
  11938. {
  11939. krb5_free_principal(*princ);
  11940. return -2;
  11941. }
  11942. plen = *cp++ << 8;
  11943. plen |= *cp++;
  11944. if (cp + plen > (CARD8 *)inbuf.data + inbuf.length)
  11945. {
  11946. krb5_free_principal(*princ);
  11947. return -2;
  11948. }
  11949. pdata = (CARD8 *)malloc(plen);
  11950. if (pdata == NULL)
  11951. {
  11952. krb5_free_principal(*princ);
  11953. return -1;
  11954. }
  11955. krb5_princ_component(*princ, i)->data = (char *)pdata;
  11956. krb5_princ_component(*princ, i)->length = plen;
  11957. memcpy(pdata, cp, plen); /* safe */
  11958. cp += plen;
  11959. krb5_princ_size(*princ)++;
  11960. }
  11961. return 0;
  11962. }
  11963. #endif /* K5_XAUTH */
  11964. #endif /* KRB5 */
  11965. #endif /* CK_FORWARD_X */
  11966. #endif /* CK_AUTHENTICATION */
  11967. /* C K _ A U T H _ I N I T
  11968. * Initialize the Kerberos system for a pending connection
  11969. * hostname - a reverse DNS lookup of the hostname when possible
  11970. * ipaddr - the ip address of the host
  11971. * username - the name the user wants to connect under not necessarily
  11972. * the same as principal
  11973. * socket - the socket handle (ttyfd in Kermit speak)
  11974. *
  11975. * Returns: 1 on success and 0 on failure
  11976. */
  11977. int
  11978. #ifdef CK_ANSIC
  11979. ck_auth_init( char * hostname, char * ipaddr, char * username, int socket )
  11980. #else /* CK_ANSIC */
  11981. ck_auth_init( hostname, ipaddr, username, socket )
  11982. char * hostname; char * ipaddr; char *username; int socket;
  11983. #endif /* CK_ANSIC */
  11984. {
  11985. #ifdef CK_AUTHENTICATION
  11986. #ifdef OS2
  11987. if ( !ck_security_loaddll() ) {
  11988. TELOPT_ME_MODE(TELOPT_AUTHENTICATION) = TN_NG_RF;
  11989. TELOPT_U_MODE(TELOPT_AUTHENTICATION) = TN_NG_RF;
  11990. return(0);
  11991. }
  11992. #endif /* OS2 */
  11993. #endif /* CK_AUTHENTICAITON */
  11994. #ifdef CK_ENCRYPTION
  11995. if ( !!ck_crypt_is_installed() ) {
  11996. TELOPT_ME_MODE(TELOPT_ENCRYPTION) = TN_NG_RF;
  11997. TELOPT_U_MODE(TELOPT_ENCRYPTION) = TN_NG_RF;
  11998. }
  11999. #endif /* CK_ENCRYPTION */
  12000. if (!hostname) hostname = "";
  12001. if (!ipaddr) ipaddr = "";
  12002. if (!username) username = "";
  12003. debug(F110,"ck_auth_init Username",username,0);
  12004. debug(F110,"ck_auth_init Hostname",hostname,0);
  12005. debug(F110,"ck_auth_init Ipaddr",ipaddr,0);
  12006. ckstrncpy( szUserName, username, UIDBUFLEN );
  12007. ckstrncpy( szHostName, hostname, UIDBUFLEN );
  12008. ckstrncpy( szIP, ipaddr, 16 );
  12009. szUserNameRequested[0] = '\0';
  12010. szUserNameAuthenticated[0] = '\0';
  12011. validUser = AUTH_REJECT;
  12012. accept_complete = 0;
  12013. authentication_version = AUTHTYPE_NULL;
  12014. #ifdef CK_AUTHENTICATION
  12015. auth_how = 0;
  12016. auth_crypt = 0;
  12017. auth_fwd = 0;
  12018. mutual_complete = 0;
  12019. if ( sstelnet )
  12020. str_data[3] = TELQUAL_REPLY;
  12021. else
  12022. str_data[3] = TELQUAL_IS;
  12023. #endif /* CK_AUTHENTICATION */
  12024. #ifdef CK_SRP
  12025. srp_waitresp = 0;
  12026. #endif /* SRP */
  12027. #ifdef CK_KERBEROS
  12028. #ifdef KRB5
  12029. /* free previous ret_cred */
  12030. if ( ret_cred ) {
  12031. #ifdef CK_ENCRYPTION
  12032. #ifdef HEIMDAL
  12033. if ( k5_session_key == &ret_cred->session)
  12034. k5_session_key = NULL;
  12035. #else /* HEIMDAL */
  12036. if ( k5_session_key == &ret_cred->keyblock)
  12037. k5_session_key = NULL;
  12038. #endif /* HEIMDAL */
  12039. #endif /* CK_ENCRYPTION */
  12040. krb5_free_creds(k5_context, ret_cred);
  12041. ret_cred = NULL;
  12042. }
  12043. if (k5_ticket) {
  12044. krb5_free_ticket(k5_context, k5_ticket);
  12045. k5_ticket = NULL;
  12046. }
  12047. /* and context */
  12048. if ( k5_context ) {
  12049. krb5_free_context(k5_context);
  12050. k5_context = NULL;
  12051. }
  12052. /* create k5_context */
  12053. krb5_init_context(&k5_context);
  12054. #ifndef MIT_CURRENT
  12055. #ifndef NO_KRB5_INIT_ETS
  12056. /* This routine is a no-op in Kerberos 1.4.x and later */
  12057. /* and in some installations it can't be found in which case */
  12058. /* define NO_KRB5_INIT_ETS */
  12059. if (k5_context)
  12060. krb5_init_ets(k5_context);
  12061. #endif /* NO_KRB5_INIT_ETS */
  12062. #endif /* MIT_CURRENT */
  12063. #ifdef KRB524_CONV
  12064. krb524_init_ets(k5_context);
  12065. #endif /* KRB524_CONV */
  12066. memset(&k5_auth,0,sizeof(k5_auth));
  12067. if (auth_context) {
  12068. krb5_auth_con_free(k5_context, auth_context);
  12069. auth_context = 0;
  12070. }
  12071. #ifdef CK_ENCRYPTION
  12072. if (k5_session_key) {
  12073. krb5_free_keyblock(k5_context, k5_session_key);
  12074. k5_session_key = 0;
  12075. }
  12076. #endif /* ENCRYPTION */
  12077. #ifdef TLS_VERIFY
  12078. krb5_tls_verified = 0;
  12079. #endif /* TLS_VERIFY */
  12080. #endif /* KRB5 */
  12081. #ifdef KRB4
  12082. #ifdef CK_ENCRYPTION
  12083. /* Initialize buffers used for authentication */
  12084. memset(&k4_session_key, 0, sizeof(k4_session_key));
  12085. memset(&k4_challenge, 0, sizeof(k4_challenge));
  12086. #endif /* CK_ENCRYPTION */
  12087. #endif /* KRB4 */
  12088. #ifdef RLOGCODE
  12089. rlog_encrypt = 0;
  12090. #endif /* RLOGCODE */
  12091. nstored = 0;
  12092. store_ptr = storage;
  12093. memset(storage,0,sizeof(storage));
  12094. #endif /* CK_KERBEROS */
  12095. #ifdef CK_ENCRYPTION
  12096. kstream_destroy();
  12097. if (!kstream_create_from_fd(socket, NULL))
  12098. return(0);
  12099. #endif /* CK_ENCRYPTION */
  12100. return(1);
  12101. }
  12102. void
  12103. auth_finished(result) int result; {
  12104. extern char uidbuf[];
  12105. extern int sstelnet;
  12106. validUser = result;
  12107. switch (result) {
  12108. case AUTH_REJECT: /* Rejected */
  12109. if (sstelnet)
  12110. uidbuf[0] = '\0';
  12111. authentication_version = AUTHTYPE_NULL;
  12112. break;
  12113. case AUTH_UNKNOWN: /* We don't know who he is, but he's okay */
  12114. if (sstelnet)
  12115. strcpy(uidbuf,"(unknown)");
  12116. break;
  12117. case AUTH_OTHER: /* We know him, but not his name */
  12118. if (sstelnet)
  12119. strcpy(uidbuf,"(other)");
  12120. break;
  12121. case AUTH_USER: /* We know he name */
  12122. case AUTH_VALID: /* We know him, and he needs no password */
  12123. if (sstelnet)
  12124. strcpy(uidbuf,szUserNameRequested);
  12125. break;
  12126. }
  12127. }
  12128. #ifdef MACOSX
  12129. #ifdef KRB5
  12130. krb5_error_code
  12131. ck_krb5_write_message(krb5_context con, krb5_pointer ptr, krb5_data *data)
  12132. {
  12133. int fd = *((int *)ptr);
  12134. long msglen;
  12135. msglen = htonl(data->length);
  12136. if (net_write(fd,(CHAR *)&msglen,4) != 4) {
  12137. return(-1);
  12138. }
  12139. if ( data->length ) {
  12140. if (net_write(fd,data->data,data->length) != data->length) {
  12141. return(-1);
  12142. }
  12143. }
  12144. return(0);
  12145. }
  12146. krb5_error_code
  12147. ck_krb5_read_message( krb5_context context,
  12148. krb5_pointer ptr,
  12149. krb5_data * data)
  12150. {
  12151. extern int ttyfd;
  12152. int fd = *((int *)ptr);
  12153. long msglen;
  12154. char *p;
  12155. int i, rc;
  12156. if (net_read(fd,&msglen,4) < 0)
  12157. return(-1);
  12158. data->length = ntohl(msglen);
  12159. if ( data->length ) {
  12160. data->data = malloc(data->length);
  12161. i = 0;
  12162. while ( i < data->length ) {
  12163. if ((rc = net_read(fd,&data->data[i],(data->length - i))) < 0)
  12164. return(-1);
  12165. i += rc;
  12166. }
  12167. }
  12168. return(0);
  12169. }
  12170. #endif /* KRB5 */
  12171. #endif /* MACOSX */
  12172. #endif /* CK_SECURITY */