sftpd_test.go 183 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795279627972798279928002801280228032804280528062807280828092810281128122813281428152816281728182819282028212822282328242825282628272828282928302831283228332834283528362837283828392840284128422843284428452846284728482849285028512852285328542855285628572858285928602861286228632864286528662867286828692870287128722873287428752876287728782879288028812882288328842885288628872888288928902891289228932894289528962897289828992900290129022903290429052906290729082909291029112912291329142915291629172918291929202921292229232924292529262927292829292930293129322933293429352936293729382939294029412942294329442945294629472948294929502951295229532954295529562957295829592960296129622963296429652966296729682969297029712972297329742975297629772978297929802981298229832984298529862987298829892990299129922993299429952996299729982999300030013002300330043005300630073008300930103011301230133014301530163017301830193020302130223023302430253026302730283029303030313032303330343035303630373038303930403041304230433044304530463047304830493050305130523053305430553056305730583059306030613062306330643065306630673068306930703071307230733074307530763077307830793080308130823083308430853086308730883089309030913092309330943095309630973098309931003101310231033104310531063107310831093110311131123113311431153116311731183119312031213122312331243125312631273128312931303131313231333134313531363137313831393140314131423143314431453146314731483149315031513152315331543155315631573158315931603161316231633164316531663167316831693170317131723173317431753176317731783179318031813182318331843185318631873188318931903191319231933194319531963197319831993200320132023203320432053206320732083209321032113212321332143215321632173218321932203221322232233224322532263227322832293230323132323233323432353236323732383239324032413242324332443245324632473248324932503251325232533254325532563257325832593260326132623263326432653266326732683269327032713272327332743275327632773278327932803281328232833284328532863287328832893290329132923293329432953296329732983299330033013302330333043305330633073308330933103311331233133314331533163317331833193320332133223323332433253326332733283329333033313332333333343335333633373338333933403341334233433344334533463347334833493350335133523353335433553356335733583359336033613362336333643365336633673368336933703371337233733374337533763377337833793380338133823383338433853386338733883389339033913392339333943395339633973398339934003401340234033404340534063407340834093410341134123413341434153416341734183419342034213422342334243425342634273428342934303431343234333434343534363437343834393440344134423443344434453446344734483449345034513452345334543455345634573458345934603461346234633464346534663467346834693470347134723473347434753476347734783479348034813482348334843485348634873488348934903491349234933494349534963497349834993500350135023503350435053506350735083509351035113512351335143515351635173518351935203521352235233524352535263527352835293530353135323533353435353536353735383539354035413542354335443545354635473548354935503551355235533554355535563557355835593560356135623563356435653566356735683569357035713572357335743575357635773578357935803581358235833584358535863587358835893590359135923593359435953596359735983599360036013602360336043605360636073608360936103611361236133614361536163617361836193620362136223623362436253626362736283629363036313632363336343635363636373638363936403641364236433644364536463647364836493650365136523653365436553656365736583659366036613662366336643665366636673668366936703671367236733674367536763677367836793680368136823683368436853686368736883689369036913692369336943695369636973698369937003701370237033704370537063707370837093710371137123713371437153716371737183719372037213722372337243725372637273728372937303731373237333734373537363737373837393740374137423743374437453746374737483749375037513752375337543755375637573758375937603761376237633764376537663767376837693770377137723773377437753776377737783779378037813782378337843785378637873788378937903791379237933794379537963797379837993800380138023803380438053806380738083809381038113812381338143815381638173818381938203821382238233824382538263827382838293830383138323833383438353836383738383839384038413842384338443845384638473848384938503851385238533854385538563857385838593860386138623863386438653866386738683869387038713872387338743875387638773878387938803881388238833884388538863887388838893890389138923893389438953896389738983899390039013902390339043905390639073908390939103911391239133914391539163917391839193920392139223923392439253926392739283929393039313932393339343935393639373938393939403941394239433944394539463947394839493950395139523953395439553956395739583959396039613962396339643965396639673968396939703971397239733974397539763977397839793980398139823983398439853986398739883989399039913992399339943995399639973998399940004001400240034004400540064007400840094010401140124013401440154016401740184019402040214022402340244025402640274028402940304031403240334034403540364037403840394040404140424043404440454046404740484049405040514052405340544055405640574058405940604061406240634064406540664067406840694070407140724073407440754076407740784079408040814082408340844085408640874088408940904091409240934094409540964097409840994100410141024103410441054106410741084109411041114112411341144115411641174118411941204121412241234124412541264127412841294130413141324133413441354136413741384139414041414142414341444145414641474148414941504151415241534154415541564157415841594160416141624163416441654166416741684169417041714172417341744175417641774178417941804181418241834184418541864187418841894190419141924193419441954196419741984199420042014202420342044205420642074208420942104211421242134214421542164217421842194220422142224223422442254226422742284229423042314232423342344235423642374238423942404241424242434244424542464247424842494250425142524253425442554256425742584259426042614262426342644265426642674268426942704271427242734274427542764277427842794280428142824283428442854286428742884289429042914292429342944295429642974298429943004301430243034304430543064307430843094310431143124313431443154316431743184319432043214322432343244325432643274328432943304331433243334334433543364337433843394340434143424343434443454346434743484349435043514352435343544355435643574358435943604361436243634364436543664367436843694370437143724373437443754376437743784379438043814382438343844385438643874388438943904391439243934394439543964397439843994400440144024403440444054406440744084409441044114412441344144415441644174418441944204421442244234424442544264427442844294430443144324433443444354436443744384439444044414442444344444445444644474448444944504451445244534454445544564457445844594460446144624463446444654466446744684469447044714472447344744475447644774478447944804481448244834484448544864487448844894490449144924493449444954496449744984499450045014502450345044505450645074508450945104511451245134514451545164517451845194520452145224523452445254526452745284529453045314532453345344535453645374538453945404541454245434544454545464547454845494550455145524553455445554556455745584559456045614562456345644565456645674568456945704571457245734574457545764577457845794580458145824583458445854586458745884589459045914592459345944595459645974598459946004601460246034604460546064607460846094610461146124613461446154616461746184619462046214622462346244625462646274628462946304631463246334634463546364637463846394640464146424643464446454646464746484649465046514652465346544655465646574658465946604661466246634664466546664667466846694670467146724673467446754676467746784679468046814682468346844685468646874688468946904691469246934694469546964697469846994700470147024703470447054706470747084709471047114712471347144715471647174718471947204721472247234724472547264727472847294730473147324733473447354736473747384739474047414742474347444745474647474748474947504751475247534754475547564757475847594760476147624763476447654766476747684769477047714772477347744775477647774778477947804781478247834784478547864787478847894790479147924793479447954796479747984799480048014802480348044805480648074808480948104811481248134814481548164817481848194820482148224823482448254826482748284829483048314832483348344835483648374838483948404841484248434844484548464847484848494850485148524853485448554856485748584859486048614862486348644865486648674868486948704871487248734874487548764877487848794880488148824883488448854886488748884889489048914892489348944895489648974898489949004901490249034904490549064907490849094910491149124913491449154916491749184919492049214922492349244925492649274928492949304931493249334934493549364937493849394940494149424943494449454946494749484949495049514952495349544955495649574958495949604961496249634964496549664967496849694970497149724973497449754976497749784979498049814982498349844985498649874988498949904991499249934994499549964997499849995000500150025003500450055006500750085009501050115012501350145015501650175018501950205021502250235024502550265027502850295030503150325033503450355036503750385039504050415042504350445045504650475048504950505051505250535054505550565057505850595060506150625063506450655066506750685069507050715072507350745075507650775078507950805081508250835084508550865087508850895090509150925093509450955096509750985099510051015102510351045105510651075108510951105111511251135114511551165117511851195120512151225123512451255126512751285129513051315132513351345135513651375138513951405141514251435144514551465147514851495150515151525153515451555156515751585159516051615162516351645165516651675168516951705171517251735174517551765177517851795180518151825183518451855186518751885189519051915192519351945195519651975198519952005201520252035204520552065207520852095210521152125213521452155216521752185219522052215222522352245225522652275228522952305231523252335234523552365237523852395240524152425243524452455246524752485249525052515252525352545255525652575258525952605261526252635264526552665267526852695270527152725273527452755276527752785279528052815282528352845285528652875288528952905291529252935294529552965297529852995300530153025303530453055306530753085309531053115312531353145315531653175318531953205321532253235324532553265327532853295330533153325333533453355336533753385339534053415342534353445345534653475348534953505351535253535354535553565357535853595360536153625363536453655366536753685369537053715372537353745375537653775378537953805381538253835384538553865387538853895390539153925393539453955396539753985399540054015402540354045405540654075408540954105411541254135414541554165417541854195420542154225423542454255426542754285429543054315432543354345435543654375438543954405441544254435444544554465447544854495450545154525453545454555456545754585459546054615462546354645465546654675468546954705471547254735474547554765477547854795480548154825483548454855486548754885489549054915492549354945495549654975498549955005501550255035504550555065507550855095510551155125513551455155516551755185519552055215522552355245525552655275528552955305531553255335534553555365537553855395540554155425543554455455546554755485549555055515552555355545555555655575558555955605561556255635564556555665567556855695570557155725573557455755576557755785579558055815582558355845585558655875588558955905591559255935594559555965597559855995600560156025603560456055606560756085609561056115612561356145615561656175618561956205621562256235624562556265627562856295630563156325633563456355636563756385639564056415642564356445645564656475648564956505651565256535654565556565657565856595660566156625663566456655666566756685669567056715672567356745675567656775678567956805681568256835684568556865687568856895690569156925693569456955696569756985699570057015702570357045705570657075708570957105711571257135714571557165717571857195720572157225723572457255726572757285729573057315732573357345735573657375738573957405741574257435744574557465747574857495750575157525753575457555756575757585759576057615762576357645765576657675768576957705771
  1. package sftpd_test
  2. import (
  3. "bufio"
  4. "bytes"
  5. "crypto/rand"
  6. "crypto/sha256"
  7. "crypto/sha512"
  8. "encoding/base64"
  9. "encoding/binary"
  10. "encoding/json"
  11. "fmt"
  12. "hash"
  13. "io"
  14. "io/ioutil"
  15. "math"
  16. "net"
  17. "net/http"
  18. "os"
  19. "os/exec"
  20. "path"
  21. "path/filepath"
  22. "runtime"
  23. "strings"
  24. "testing"
  25. "time"
  26. _ "github.com/go-sql-driver/mysql"
  27. _ "github.com/lib/pq"
  28. _ "github.com/mattn/go-sqlite3"
  29. "golang.org/x/crypto/ssh"
  30. "github.com/drakkan/sftpgo/config"
  31. "github.com/drakkan/sftpgo/dataprovider"
  32. "github.com/drakkan/sftpgo/httpd"
  33. "github.com/drakkan/sftpgo/logger"
  34. "github.com/drakkan/sftpgo/sftpd"
  35. "github.com/drakkan/sftpgo/utils"
  36. "github.com/drakkan/sftpgo/vfs"
  37. "github.com/pkg/sftp"
  38. "github.com/rs/zerolog"
  39. )
  40. const (
  41. logSender = "sftpdTesting"
  42. sftpServerAddr = "127.0.0.1:2022"
  43. defaultUsername = "test_user_sftp"
  44. defaultPassword = "test_password"
  45. testPubKey = "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQC03jj0D+djk7pxIf/0OhrxrchJTRZklofJ1NoIu4752Sq02mdXmarMVsqJ1cAjV5LBVy3D1F5U6XW4rppkXeVtd04Pxb09ehtH0pRRPaoHHlALiJt8CoMpbKYMA8b3KXPPriGxgGomvtU2T2RMURSwOZbMtpsugfjYSWenyYX+VORYhylWnSXL961LTyC21ehd6d6QnW9G7E5hYMITMY9TuQZz3bROYzXiTsgN0+g6Hn7exFQp50p45StUMfV/SftCMdCxlxuyGny2CrN/vfjO7xxOo2uv7q1qm10Q46KPWJQv+pgZ/OfL+EDjy07n5QVSKHlbx+2nT4Q0EgOSQaCTYwn3YjtABfIxWwgAFdyj6YlPulCL22qU4MYhDcA6PSBwDdf8hvxBfvsiHdM+JcSHvv8/VeJhk6CmnZxGY0fxBupov27z3yEO8nAg8k+6PaUiW1MSUfuGMF/ktB8LOstXsEPXSszuyXiOv4DaryOXUiSn7bmRqKcEFlJusO6aZP0= nicola@p1"
  46. testPubKey1 = "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQCd60+/j+y8f0tLftihWV1YN9RSahMI9btQMDIMqts/jeNbD8jgoogM3nhF7KxfcaMKURuD47KC4Ey6iAJUJ0sWkSNNxOcIYuvA+5MlspfZDsa8Ag76Fe1vyz72WeHMHMeh/hwFo2TeIeIXg480T1VI6mzfDrVp2GzUx0SS0dMsQBjftXkuVR8YOiOwMCAH2a//M1OrvV7d/NBk6kBN0WnuIBb2jKm15PAA7+jQQG7tzwk2HedNH3jeL5GH31xkSRwlBczRK0xsCQXehAlx6cT/e/s44iJcJTHfpPKoSk6UAhPJYe7Z1QnuoawY9P9jQaxpyeImBZxxUEowhjpj2avBxKdRGBVK8R7EL8tSOeLbhdyWe5Mwc1+foEbq9Zz5j5Kd+hn3Wm1UnsGCrXUUUoZp1jnlNl0NakCto+5KmqnT9cHxaY+ix2RLUWAZyVFlRq71OYux1UHJnEJPiEI1/tr4jFBSL46qhQZv/TfpkfVW8FLz0lErfqu0gQEZnNHr3Fc= nicola@p1"
  47. testPrivateKey = `-----BEGIN OPENSSH PRIVATE KEY-----
  48. b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAABlwAAAAdzc2gtcn
  49. NhAAAAAwEAAQAAAYEAtN449A/nY5O6cSH/9Doa8a3ISU0WZJaHydTaCLuO+dkqtNpnV5mq
  50. zFbKidXAI1eSwVctw9ReVOl1uK6aZF3lbXdOD8W9PXobR9KUUT2qBx5QC4ibfAqDKWymDA
  51. PG9ylzz64hsYBqJr7VNk9kTFEUsDmWzLabLoH42Elnp8mF/lTkWIcpVp0ly/etS08gttXo
  52. XenekJ1vRuxOYWDCEzGPU7kGc920TmM14k7IDdPoOh5+3sRUKedKeOUrVDH1f0n7QjHQsZ
  53. cbshp8tgqzf734zu8cTqNrr+6taptdEOOij1iUL/qYGfzny/hA48tO5+UFUih5W8ftp0+E
  54. NBIDkkGgk2MJ92I7QAXyMVsIABXco+mJT7pQi9tqlODGIQ3AOj0gcA3X/Ib8QX77Ih3TPi
  55. XEh77/P1XiYZOgpp2cRmNH8QbqaL9u898hDvJwIPJPuj2lIltTElH7hjBf5LQfCzrLV7BD
  56. 10rM7sl4jr+A2q8jl1Ikp+25kainBBZSbrDummT9AAAFgDU/VLk1P1S5AAAAB3NzaC1yc2
  57. EAAAGBALTeOPQP52OTunEh//Q6GvGtyElNFmSWh8nU2gi7jvnZKrTaZ1eZqsxWyonVwCNX
  58. ksFXLcPUXlTpdbiummRd5W13Tg/FvT16G0fSlFE9qgceUAuIm3wKgylspgwDxvcpc8+uIb
  59. GAaia+1TZPZExRFLA5lsy2my6B+NhJZ6fJhf5U5FiHKVadJcv3rUtPILbV6F3p3pCdb0bs
  60. TmFgwhMxj1O5BnPdtE5jNeJOyA3T6Doeft7EVCnnSnjlK1Qx9X9J+0Ix0LGXG7IafLYKs3
  61. +9+M7vHE6ja6/urWqbXRDjoo9YlC/6mBn858v4QOPLTuflBVIoeVvH7adPhDQSA5JBoJNj
  62. CfdiO0AF8jFbCAAV3KPpiU+6UIvbapTgxiENwDo9IHAN1/yG/EF++yId0z4lxIe+/z9V4m
  63. GToKadnEZjR/EG6mi/bvPfIQ7ycCDyT7o9pSJbUxJR+4YwX+S0Hws6y1ewQ9dKzO7JeI6/
  64. gNqvI5dSJKftuZGopwQWUm6w7ppk/QAAAAMBAAEAAAGAHKnC+Nq0XtGAkIFE4N18e6SAwy
  65. 0WSWaZqmCzFQM0S2AhJnweOIG/0ZZHjsRzKKauOTmppQk40dgVsejpytIek9R+aH172gxJ
  66. 2n4Cx0UwduRU5x8FFQlNc/kl722B0JWfJuB/snOZXv6LJ4o5aObIkozt2w9tVFeAqjYn2S
  67. 1UsNOfRHBXGsTYwpRDwFWP56nKo2d2wBBTHDhCy6fb2dLW1fvSi/YspueOGIlHpvlYKi2/
  68. CWqvs9xVrwcScMtiDoQYq0khhO0efLCxvg/o+W9CLMVM2ms4G1zoSUQKN0oYWWQJyW4+VI
  69. YneWO8UpN0J3ElXKi7bhgAat7dBaM1g9IrAzk153DiEFZNsPxGOgL/+YdQN7zUBx/z7EkI
  70. jyv80RV7fpUXvcq2p+qNl6UVig3VSzRrnsaJkUWu/A0u59ha7ocv6NxDIXjxpIDJme16GF
  71. quiGVBQNnYJymS/vFEbGf6bgf7iRmMCRUMG4nqLA6fPYP9uAtch+CmDfVLZC/fIdC5AAAA
  72. wQCDissV4zH6bfqgxJSuYNk8Vbb+19cF3b7gH1rVlB3zxpCAgcRgMHC+dP1z2NRx7UW9MR
  73. nye6kjpkzZZ0OigLqo7TtEq8uTglD9o6W7mRXqhy5A/ySOmqPL3ernHHQhGuoNODYAHkOU
  74. u2Rh8HXi+VLwKZcLInPOYJvcuLG4DxN8WfeVvlMHwhAOaTNNOtL4XZDHQeIPc4qHmJymmv
  75. sV7GuyQ6yW5C10uoGdxRPd90Bh4z4h2bKfZFjvEBbSBVkqrlAAAADBAN/zNtNayd/dX7Cr
  76. Nb4sZuzCh+CW4BH8GOePZWNCATwBbNXBVb5cR+dmuTqYm+Ekz0VxVQRA1TvKncluJOQpoa
  77. Xj8r0xdIgqkehnfDPMKtYVor06B9Fl1jrXtXU0Vrr6QcBWruSVyK1ZxqcmcNK/+KolVepe
  78. A6vcl/iKaG4U7su166nxLST06M2EgcSVsFJHpKn5+WAXC+X0Gx8kNjWIIb3GpiChdc0xZD
  79. mq02xZthVJrTCVw/e7gfDoB2QRsNV8HwAAAMEAzsCghZVp+0YsYg9oOrw4tEqcbEXEMhwY
  80. 0jW8JNL8Spr1Ibp5Dw6bRSk5azARjmJtnMJhJ3oeHfF0eoISqcNuQXGndGQbVM9YzzAzc1
  81. NbbCNsVroqKlChT5wyPNGS+phi2bPARBno7WSDvshTZ7dAVEP2c9MJW0XwoSevwKlhgSdt
  82. RLFFQ/5nclJSdzPBOmQouC0OBcMFSrYtMeknJ4VvueVvve5HcHFaEsaMc7ABAGaLYaBQOm
  83. iixITGvaNZh/tjAAAACW5pY29sYUBwMQE=
  84. -----END OPENSSH PRIVATE KEY-----`
  85. configDir = ".."
  86. )
  87. var (
  88. allPerms = []string{dataprovider.PermAny}
  89. homeBasePath string
  90. scpPath string
  91. gitPath string
  92. sshPath string
  93. pubKeyPath string
  94. privateKeyPath string
  95. gitWrapPath string
  96. extAuthPath string
  97. keyIntAuthPath string
  98. preLoginPath string
  99. logFilePath string
  100. )
  101. func TestMain(m *testing.M) {
  102. logFilePath = filepath.Join(configDir, "sftpgo_sftpd_test.log")
  103. loginBannerFileName := "login_banner"
  104. loginBannerFile := filepath.Join(configDir, loginBannerFileName)
  105. ioutil.WriteFile(loginBannerFile, []byte("simple login banner\n"), 0777)
  106. logger.InitLogger(logFilePath, 5, 1, 28, false, zerolog.DebugLevel)
  107. config.LoadConfig(configDir, "")
  108. providerConf := config.GetProviderConf()
  109. err := dataprovider.Initialize(providerConf, configDir)
  110. if err != nil {
  111. logger.Warn(logSender, "", "error initializing data provider: %v", err)
  112. os.Exit(1)
  113. }
  114. httpConfig := config.GetHTTPConfig()
  115. httpConfig.Initialize(configDir)
  116. dataProvider := dataprovider.GetProvider()
  117. sftpdConf := config.GetSFTPDConfig()
  118. httpdConf := config.GetHTTPDConfig()
  119. sftpdConf.BindPort = 2022
  120. sftpdConf.KexAlgorithms = []string{"[email protected]", "ecdh-sha2-nistp256",
  121. "ecdh-sha2-nistp384"}
  122. sftpdConf.Ciphers = []string{"[email protected]", "[email protected]",
  123. "aes256-ctr"}
  124. sftpdConf.MACs = []string{"[email protected]", "hmac-sha2-256"}
  125. sftpdConf.LoginBannerFile = loginBannerFileName
  126. // we need to test all supported ssh commands
  127. sftpdConf.EnabledSSHCommands = []string{"*"}
  128. // we run the test cases with UploadMode atomic and resume support. The non atomic code path
  129. // simply does not execute some code so if it works in atomic mode will
  130. // work in non atomic mode too
  131. sftpdConf.UploadMode = 2
  132. homeBasePath = os.TempDir()
  133. var scriptArgs string
  134. if runtime.GOOS == "windows" {
  135. scriptArgs = "%*"
  136. } else {
  137. sftpdConf.Actions.ExecuteOn = []string{"download", "upload", "rename", "delete", "ssh_cmd"}
  138. sftpdConf.Actions.Command = "/usr/bin/true"
  139. sftpdConf.Actions.HTTPNotificationURL = "http://127.0.0.1:8083/"
  140. scriptArgs = "$@"
  141. }
  142. keyIntAuthPath = filepath.Join(homeBasePath, "keyintauth.sh")
  143. ioutil.WriteFile(keyIntAuthPath, getKeyboardInteractiveScriptContent([]string{"1", "2"}, 0, false, 1), 0755)
  144. sftpdConf.KeyboardInteractiveHook = keyIntAuthPath
  145. scpPath, err = exec.LookPath("scp")
  146. if err != nil {
  147. logger.Warn(logSender, "", "unable to get scp command. SCP tests will be skipped, err: %v", err)
  148. logger.WarnToConsole("unable to get scp command. SCP tests will be skipped, err: %v", err)
  149. scpPath = ""
  150. }
  151. gitPath, err = exec.LookPath("git")
  152. if err != nil {
  153. logger.Warn(logSender, "", "unable to get git command. GIT tests will be skipped, err: %v", err)
  154. logger.WarnToConsole("unable to get git command. GIT tests will be skipped, err: %v", err)
  155. gitPath = ""
  156. }
  157. sshPath, err = exec.LookPath("ssh")
  158. if err != nil {
  159. logger.Warn(logSender, "", "unable to get ssh command. GIT tests will be skipped, err: %v", err)
  160. logger.WarnToConsole("unable to get ssh command. GIT tests will be skipped, err: %v", err)
  161. gitPath = ""
  162. }
  163. pubKeyPath = filepath.Join(homeBasePath, "ssh_key.pub")
  164. privateKeyPath = filepath.Join(homeBasePath, "ssh_key")
  165. gitWrapPath = filepath.Join(homeBasePath, "gitwrap.sh")
  166. extAuthPath = filepath.Join(homeBasePath, "extauth.sh")
  167. preLoginPath = filepath.Join(homeBasePath, "prelogin.sh")
  168. err = ioutil.WriteFile(pubKeyPath, []byte(testPubKey+"\n"), 0600)
  169. if err != nil {
  170. logger.WarnToConsole("unable to save public key to file: %v", err)
  171. }
  172. err = ioutil.WriteFile(privateKeyPath, []byte(testPrivateKey+"\n"), 0600)
  173. if err != nil {
  174. logger.WarnToConsole("unable to save private key to file: %v", err)
  175. }
  176. err = ioutil.WriteFile(gitWrapPath, []byte(fmt.Sprintf("%v -i %v -oStrictHostKeyChecking=no %v\n",
  177. sshPath, privateKeyPath, scriptArgs)), 0755)
  178. if err != nil {
  179. logger.WarnToConsole("unable to save gitwrap shell script: %v", err)
  180. }
  181. sftpd.SetDataProvider(dataProvider)
  182. httpd.SetDataProvider(dataProvider)
  183. go func() {
  184. logger.Debug(logSender, "", "initializing SFTP server with config %+v", sftpdConf)
  185. if err := sftpdConf.Initialize(configDir); err != nil {
  186. logger.Error(logSender, "", "could not start SFTP server: %v", err)
  187. }
  188. }()
  189. go func() {
  190. if err := httpdConf.Initialize(configDir, false); err != nil {
  191. logger.Error(logSender, "", "could not start HTTP server: %v", err)
  192. }
  193. }()
  194. waitTCPListening(fmt.Sprintf("%s:%d", sftpdConf.BindAddress, sftpdConf.BindPort))
  195. waitTCPListening(fmt.Sprintf("%s:%d", httpdConf.BindAddress, httpdConf.BindPort))
  196. sftpdConf.BindPort = 2222
  197. sftpdConf.ProxyProtocol = 1
  198. go func() {
  199. logger.Debug(logSender, "", "initializing SFTP server with config %+v", sftpdConf)
  200. if err := sftpdConf.Initialize(configDir); err != nil {
  201. logger.Error(logSender, "", "could not start SFTP server: %v", err)
  202. }
  203. }()
  204. waitTCPListening(fmt.Sprintf("%s:%d", sftpdConf.BindAddress, sftpdConf.BindPort))
  205. sftpdConf.BindPort = 2224
  206. sftpdConf.ProxyProtocol = 2
  207. go func() {
  208. logger.Debug(logSender, "", "initializing SFTP server with config %+v", sftpdConf)
  209. if err := sftpdConf.Initialize(configDir); err != nil {
  210. logger.Error(logSender, "", "could not start SFTP server: %v", err)
  211. }
  212. }()
  213. waitTCPListening(fmt.Sprintf("%s:%d", sftpdConf.BindAddress, sftpdConf.BindPort))
  214. exitCode := m.Run()
  215. os.Remove(logFilePath)
  216. os.Remove(loginBannerFile)
  217. os.Remove(pubKeyPath)
  218. os.Remove(privateKeyPath)
  219. os.Remove(gitWrapPath)
  220. os.Remove(extAuthPath)
  221. os.Remove(preLoginPath)
  222. os.Remove(keyIntAuthPath)
  223. os.Exit(exitCode)
  224. }
  225. func TestInitialization(t *testing.T) {
  226. config.LoadConfig(configDir, "")
  227. sftpdConf := config.GetSFTPDConfig()
  228. sftpdConf.Umask = "invalid umask"
  229. sftpdConf.BindPort = 2022
  230. sftpdConf.LoginBannerFile = "invalid_file"
  231. sftpdConf.EnabledSSHCommands = append(sftpdConf.EnabledSSHCommands, "ls")
  232. err := sftpdConf.Initialize(configDir)
  233. if err == nil {
  234. t.Error("Inizialize must fail, a SFTP server should be already running")
  235. }
  236. sftpdConf.KeyboardInteractiveHook = "invalid_file"
  237. err = sftpdConf.Initialize(configDir)
  238. if err == nil {
  239. t.Error("Inizialize must fail, a SFTP server should be already running")
  240. }
  241. sftpdConf.KeyboardInteractiveHook = filepath.Join(homeBasePath, "invalid_file")
  242. err = sftpdConf.Initialize(configDir)
  243. if err == nil {
  244. t.Error("Inizialize must fail, a SFTP server should be already running")
  245. }
  246. sftpdConf.BindPort = 4444
  247. sftpdConf.ProxyProtocol = 1
  248. sftpdConf.ProxyAllowed = []string{"1270.0.0.1"}
  249. err = sftpdConf.Initialize(configDir)
  250. if err == nil {
  251. t.Error("Inizialize must fail, proxy IP allowed is invalid")
  252. }
  253. }
  254. func TestBasicSFTPHandling(t *testing.T) {
  255. usePubKey := false
  256. u := getTestUser(usePubKey)
  257. u.QuotaSize = 6553600
  258. user, _, err := httpd.AddUser(u, http.StatusOK)
  259. if err != nil {
  260. t.Errorf("unable to add user: %v", err)
  261. }
  262. os.RemoveAll(user.GetHomeDir())
  263. client, err := getSftpClient(user, usePubKey)
  264. if err != nil {
  265. t.Errorf("unable to create sftp client: %v", err)
  266. } else {
  267. defer client.Close()
  268. testFileName := "test_file.dat"
  269. testFilePath := filepath.Join(homeBasePath, testFileName)
  270. testFileSize := int64(65535)
  271. expectedQuotaSize := user.UsedQuotaSize + testFileSize
  272. expectedQuotaFiles := user.UsedQuotaFiles + 1
  273. createTestFile(testFilePath, testFileSize)
  274. err = sftpUploadFile(testFilePath, path.Join("/missing_dir", testFileName), testFileSize, client)
  275. if err == nil {
  276. t.Errorf("upload a file to a missing dir must fail")
  277. }
  278. err = sftpUploadFile(testFilePath, testFileName, testFileSize, client)
  279. if err != nil {
  280. t.Errorf("file upload error: %v", err)
  281. }
  282. localDownloadPath := filepath.Join(homeBasePath, "test_download.dat")
  283. err = sftpDownloadFile(testFileName, localDownloadPath, testFileSize, client)
  284. if err != nil {
  285. t.Errorf("file download error: %v", err)
  286. }
  287. user, _, err = httpd.GetUserByID(user.ID, http.StatusOK)
  288. if err != nil {
  289. t.Errorf("error getting user: %v", err)
  290. }
  291. if expectedQuotaFiles != user.UsedQuotaFiles {
  292. t.Errorf("quota files does not match, expected: %v, actual: %v", expectedQuotaFiles, user.UsedQuotaFiles)
  293. }
  294. if expectedQuotaSize != user.UsedQuotaSize {
  295. t.Errorf("quota size does not match, expected: %v, actual: %v", expectedQuotaSize, user.UsedQuotaSize)
  296. }
  297. err = client.Remove(testFileName)
  298. if err != nil {
  299. t.Errorf("error removing uploaded file: %v", err)
  300. }
  301. _, err = client.Lstat(testFileName)
  302. if err == nil {
  303. t.Errorf("stat for deleted file must not succeed")
  304. }
  305. user, _, err = httpd.GetUserByID(user.ID, http.StatusOK)
  306. if err != nil {
  307. t.Errorf("error getting user: %v", err)
  308. }
  309. if (expectedQuotaFiles - 1) != user.UsedQuotaFiles {
  310. t.Errorf("quota files does not match after delete, expected: %v, actual: %v", expectedQuotaFiles-1, user.UsedQuotaFiles)
  311. }
  312. if (expectedQuotaSize - testFileSize) != user.UsedQuotaSize {
  313. t.Errorf("quota size does not match, expected: %v, actual: %v", expectedQuotaSize-testFileSize, user.UsedQuotaSize)
  314. }
  315. os.Remove(testFilePath)
  316. os.Remove(localDownloadPath)
  317. }
  318. _, err = httpd.RemoveUser(user, http.StatusOK)
  319. if err != nil {
  320. t.Errorf("unable to remove user: %v", err)
  321. }
  322. os.RemoveAll(user.GetHomeDir())
  323. }
  324. func TestProxyProtocol(t *testing.T) {
  325. usePubKey := false
  326. user, _, err := httpd.AddUser(getTestUser(usePubKey), http.StatusOK)
  327. if err != nil {
  328. t.Errorf("unable to add user: %v", err)
  329. }
  330. // remove the home dir to test auto creation
  331. os.RemoveAll(user.HomeDir)
  332. client, err := getSftpClientWithAddr(user, usePubKey, "127.0.0.1:2222")
  333. if err != nil {
  334. t.Errorf("unable to create sftp client: %v", err)
  335. } else {
  336. defer client.Close()
  337. _, err = client.Getwd()
  338. if err != nil {
  339. t.Errorf("error mkdir: %v", err)
  340. }
  341. }
  342. client, err = getSftpClientWithAddr(user, usePubKey, "127.0.0.1:2224")
  343. if err == nil {
  344. t.Error("request without a proxy header must be rejected")
  345. }
  346. httpd.RemoveUser(user, http.StatusOK)
  347. os.RemoveAll(user.GetHomeDir())
  348. }
  349. func TestUploadResume(t *testing.T) {
  350. usePubKey := false
  351. u := getTestUser(usePubKey)
  352. user, _, err := httpd.AddUser(u, http.StatusOK)
  353. if err != nil {
  354. t.Errorf("unable to add user: %v", err)
  355. }
  356. os.RemoveAll(user.GetHomeDir())
  357. client, err := getSftpClient(user, usePubKey)
  358. if err != nil {
  359. t.Errorf("unable to create sftp client: %v", err)
  360. } else {
  361. defer client.Close()
  362. testFileName := "test_file.dat"
  363. testFilePath := filepath.Join(homeBasePath, testFileName)
  364. testFileSize := int64(65535)
  365. appendDataSize := int64(65535)
  366. err = createTestFile(testFilePath, testFileSize)
  367. if err != nil {
  368. t.Errorf("unable to create test file: %v", err)
  369. }
  370. err = sftpUploadFile(testFilePath, testFileName, testFileSize, client)
  371. if err != nil {
  372. t.Errorf("file upload error: %v", err)
  373. }
  374. err = appendToTestFile(testFilePath, appendDataSize)
  375. if err != nil {
  376. t.Errorf("unable to append to test file: %v", err)
  377. }
  378. err = sftpUploadResumeFile(testFilePath, testFileName, testFileSize+appendDataSize, false, client)
  379. if err != nil {
  380. t.Errorf("file upload resume error: %v", err)
  381. }
  382. localDownloadPath := filepath.Join(homeBasePath, "test_download.dat")
  383. err = sftpDownloadFile(testFileName, localDownloadPath, testFileSize+appendDataSize, client)
  384. if err != nil {
  385. t.Errorf("file download error: %v", err)
  386. }
  387. initialHash, err := computeHashForFile(sha256.New(), testFilePath)
  388. if err != nil {
  389. t.Errorf("error computing file hash: %v", err)
  390. }
  391. donwloadedFileHash, err := computeHashForFile(sha256.New(), localDownloadPath)
  392. if err != nil {
  393. t.Errorf("error computing downloaded file hash: %v", err)
  394. }
  395. if donwloadedFileHash != initialHash {
  396. t.Errorf("resume failed: file hash does not match")
  397. }
  398. err = sftpUploadResumeFile(testFilePath, testFileName, testFileSize+appendDataSize, true, client)
  399. if err == nil {
  400. t.Errorf("file upload resume with invalid offset must fail")
  401. }
  402. os.Remove(testFilePath)
  403. os.Remove(localDownloadPath)
  404. }
  405. _, err = httpd.RemoveUser(user, http.StatusOK)
  406. if err != nil {
  407. t.Errorf("unable to remove user: %v", err)
  408. }
  409. os.RemoveAll(user.GetHomeDir())
  410. }
  411. func TestDirCommands(t *testing.T) {
  412. usePubKey := false
  413. user, _, err := httpd.AddUser(getTestUser(usePubKey), http.StatusOK)
  414. if err != nil {
  415. t.Errorf("unable to add user: %v", err)
  416. }
  417. // remove the home dir to test auto creation
  418. os.RemoveAll(user.HomeDir)
  419. client, err := getSftpClient(user, usePubKey)
  420. if err != nil {
  421. t.Errorf("unable to create sftp client: %v", err)
  422. } else {
  423. defer client.Close()
  424. err = client.Mkdir("test1")
  425. if err != nil {
  426. t.Errorf("error mkdir: %v", err)
  427. }
  428. err = client.Rename("test1", "test")
  429. if err != nil {
  430. t.Errorf("error rename: %v", err)
  431. }
  432. _, err = client.Lstat("/test1")
  433. if err == nil {
  434. t.Errorf("stat for renamed dir must not succeed")
  435. }
  436. err = client.PosixRename("test", "test1")
  437. if err != nil {
  438. t.Errorf("error posix rename: %v", err)
  439. }
  440. err = client.Remove("test1")
  441. if err != nil {
  442. t.Errorf("error rmdir: %v", err)
  443. }
  444. err = client.Mkdir("/test/test1")
  445. if err == nil {
  446. t.Errorf("recursive mkdir must fail")
  447. }
  448. client.Mkdir("/test")
  449. err = client.Mkdir("/test/test1")
  450. if err != nil {
  451. t.Errorf("mkdir dir error: %v", err)
  452. }
  453. _, err = client.ReadDir("/this/dir/does/not/exist")
  454. if err == nil {
  455. t.Errorf("reading a missing dir must fail")
  456. }
  457. err = client.RemoveDirectory("/test/test1")
  458. if err != nil {
  459. t.Errorf("remove dir error: %v", err)
  460. }
  461. err = client.RemoveDirectory("/test")
  462. if err != nil {
  463. t.Errorf("remove dir error: %v", err)
  464. }
  465. _, err = client.Lstat("/test")
  466. if err == nil {
  467. t.Errorf("stat for deleted dir must not succeed")
  468. }
  469. err = client.RemoveDirectory("/test")
  470. if err == nil {
  471. t.Errorf("remove missing path must fail")
  472. }
  473. }
  474. httpd.RemoveUser(user, http.StatusOK)
  475. os.RemoveAll(user.GetHomeDir())
  476. }
  477. func TestRemove(t *testing.T) {
  478. usePubKey := true
  479. user, _, err := httpd.AddUser(getTestUser(usePubKey), http.StatusOK)
  480. if err != nil {
  481. t.Errorf("unable to add user: %v", err)
  482. }
  483. client, err := getSftpClient(user, usePubKey)
  484. if err != nil {
  485. t.Errorf("unable to create sftp client: %v", err)
  486. } else {
  487. defer client.Close()
  488. err = client.Mkdir("test")
  489. if err != nil {
  490. t.Errorf("error mkdir: %v", err)
  491. }
  492. err = client.Mkdir("/test/test1")
  493. if err != nil {
  494. t.Errorf("error mkdir subdir: %v", err)
  495. }
  496. testFileName := "/test_file.dat"
  497. testFilePath := filepath.Join(homeBasePath, testFileName)
  498. testFileSize := int64(65535)
  499. err = createTestFile(testFilePath, testFileSize)
  500. if err != nil {
  501. t.Errorf("unable to create test file: %v", err)
  502. }
  503. err = sftpUploadFile(testFilePath, path.Join("/test", testFileName), testFileSize, client)
  504. if err != nil {
  505. t.Errorf("file upload error: %v", err)
  506. }
  507. err = client.Remove("/test")
  508. if err == nil {
  509. t.Errorf("remove non empty dir must fail")
  510. }
  511. err = client.RemoveDirectory(path.Join("/test", testFileName))
  512. if err == nil {
  513. t.Errorf("remove a file with rmdir must fail")
  514. }
  515. err = client.Remove(path.Join("/test", testFileName))
  516. if err != nil {
  517. t.Errorf("remove file error: %v", err)
  518. }
  519. err = client.Remove(path.Join("/test", testFileName))
  520. if err == nil {
  521. t.Errorf("remove missing file must fail")
  522. }
  523. err = client.Remove("/test/test1")
  524. if err != nil {
  525. t.Errorf("remove dir error: %v", err)
  526. }
  527. err = client.Remove("/test")
  528. if err != nil {
  529. t.Errorf("remove dir error: %v", err)
  530. }
  531. os.Remove(testFilePath)
  532. }
  533. _, err = httpd.RemoveUser(user, http.StatusOK)
  534. if err != nil {
  535. t.Errorf("unable to remove user: %v", err)
  536. }
  537. os.RemoveAll(user.GetHomeDir())
  538. }
  539. func TestLink(t *testing.T) {
  540. usePubKey := false
  541. user, _, err := httpd.AddUser(getTestUser(usePubKey), http.StatusOK)
  542. if err != nil {
  543. t.Errorf("unable to add user: %v", err)
  544. }
  545. client, err := getSftpClient(user, usePubKey)
  546. if err != nil {
  547. t.Errorf("unable to create sftp client: %v", err)
  548. } else {
  549. defer client.Close()
  550. testFileName := "test_file.dat"
  551. testFilePath := filepath.Join(homeBasePath, testFileName)
  552. testFileSize := int64(65535)
  553. err = createTestFile(testFilePath, testFileSize)
  554. if err != nil {
  555. t.Errorf("unable to create test file: %v", err)
  556. }
  557. err = sftpUploadFile(testFilePath, testFileName, testFileSize, client)
  558. if err != nil {
  559. t.Errorf("file upload error: %v", err)
  560. }
  561. err = client.Symlink(testFileName, testFileName+".link")
  562. if err != nil {
  563. t.Errorf("error creating symlink: %v", err)
  564. }
  565. _, err = client.ReadLink(testFileName + ".link")
  566. if err == nil {
  567. t.Errorf("readlink is currently not implemented so must fail")
  568. }
  569. err = client.Symlink(testFileName, testFileName+".link")
  570. if err == nil {
  571. t.Errorf("creating a symlink to an existing one must fail")
  572. }
  573. err = client.Link(testFileName, testFileName+".hlink")
  574. if err == nil {
  575. t.Errorf("hard link is not supported and must fail")
  576. }
  577. err = client.Remove(testFileName + ".link")
  578. if err != nil {
  579. t.Errorf("error removing symlink: %v", err)
  580. }
  581. err = client.Remove(testFileName)
  582. if err != nil {
  583. t.Errorf("error removing uploaded file: %v", err)
  584. }
  585. os.Remove(testFilePath)
  586. }
  587. _, err = httpd.RemoveUser(user, http.StatusOK)
  588. if err != nil {
  589. t.Errorf("unable to remove user: %v", err)
  590. }
  591. os.RemoveAll(user.GetHomeDir())
  592. }
  593. func TestStat(t *testing.T) {
  594. usePubKey := false
  595. user, _, err := httpd.AddUser(getTestUser(usePubKey), http.StatusOK)
  596. if err != nil {
  597. t.Errorf("unable to add user: %v", err)
  598. }
  599. client, err := getSftpClient(user, usePubKey)
  600. if err != nil {
  601. t.Errorf("unable to create sftp client: %v", err)
  602. } else {
  603. defer client.Close()
  604. testFileName := "test_file.dat"
  605. testFilePath := filepath.Join(homeBasePath, testFileName)
  606. testFileSize := int64(65535)
  607. createTestFile(testFilePath, testFileSize)
  608. err = sftpUploadFile(testFilePath, testFileName, testFileSize, client)
  609. if err != nil {
  610. t.Errorf("file upload error: %v", err)
  611. }
  612. _, err := client.Lstat(testFileName)
  613. if err != nil {
  614. t.Errorf("stat error: %v", err)
  615. }
  616. // mode 0666 and 0444 works on Windows too
  617. newPerm := os.FileMode(0666)
  618. err = client.Chmod(testFileName, newPerm)
  619. if err != nil {
  620. t.Errorf("chmod error: %v", err)
  621. }
  622. newFi, err := client.Lstat(testFileName)
  623. if err != nil {
  624. t.Errorf("stat error: %v", err)
  625. }
  626. if newPerm != newFi.Mode().Perm() {
  627. t.Errorf("chmod failed expected: %v, actual: %v", newPerm, newFi.Mode().Perm())
  628. }
  629. newPerm = os.FileMode(0444)
  630. err = client.Chmod(testFileName, newPerm)
  631. if err != nil {
  632. t.Errorf("chmod error: %v", err)
  633. }
  634. newFi, err = client.Lstat(testFileName)
  635. if err != nil {
  636. t.Errorf("stat error: %v", err)
  637. }
  638. if newPerm != newFi.Mode().Perm() {
  639. t.Errorf("chmod failed expected: %v, actual: %v", newPerm, newFi.Mode().Perm())
  640. }
  641. _, err = client.ReadLink(testFileName)
  642. if err == nil {
  643. t.Errorf("readlink is not supported and must fail")
  644. }
  645. err = client.Truncate(testFileName, 0)
  646. if err != nil {
  647. t.Errorf("truncate must be silently ignored: %v", err)
  648. }
  649. os.Remove(testFilePath)
  650. }
  651. _, err = httpd.RemoveUser(user, http.StatusOK)
  652. if err != nil {
  653. t.Errorf("unable to remove user: %v", err)
  654. }
  655. os.RemoveAll(user.GetHomeDir())
  656. }
  657. func TestStatChownChmod(t *testing.T) {
  658. if runtime.GOOS == "windows" {
  659. t.Skip("chown is not supported on Windows, chmod is partially supported")
  660. }
  661. usePubKey := true
  662. user, _, err := httpd.AddUser(getTestUser(usePubKey), http.StatusOK)
  663. if err != nil {
  664. t.Errorf("unable to add user: %v", err)
  665. }
  666. client, err := getSftpClient(user, usePubKey)
  667. if err != nil {
  668. t.Errorf("unable to create sftp client: %v", err)
  669. } else {
  670. defer client.Close()
  671. testFileName := "test_file.dat"
  672. testFilePath := filepath.Join(homeBasePath, testFileName)
  673. testFileSize := int64(65535)
  674. createTestFile(testFilePath, testFileSize)
  675. err = sftpUploadFile(testFilePath, testFileName, testFileSize, client)
  676. if err != nil {
  677. t.Errorf("file upload error: %v", err)
  678. }
  679. err = client.Chown(testFileName, os.Getuid(), os.Getgid())
  680. if err != nil {
  681. t.Errorf("chown error: %v", err)
  682. }
  683. newPerm := os.FileMode(0600)
  684. err = client.Chmod(testFileName, newPerm)
  685. if err != nil {
  686. t.Errorf("chmod error: %v", err)
  687. }
  688. newFi, err := client.Lstat(testFileName)
  689. if err != nil {
  690. t.Errorf("stat error: %v", err)
  691. }
  692. if newPerm != newFi.Mode().Perm() {
  693. t.Errorf("chown failed expected: %v, actual: %v", newPerm, newFi.Mode().Perm())
  694. }
  695. err = client.Remove(testFileName)
  696. if err != nil {
  697. t.Errorf("error removing uploaded file: %v", err)
  698. }
  699. // l'errore viene riconvertito da sftp.ErrSSHFxNoSuchFile in os.ErrNotExist
  700. err = client.Chmod(testFileName, newPerm)
  701. if err != os.ErrNotExist {
  702. t.Errorf("unexpected chmod error: %v expected: %v", err, os.ErrNotExist)
  703. }
  704. err = client.Chown(testFileName, os.Getuid(), os.Getgid())
  705. if err != os.ErrNotExist {
  706. t.Errorf("unexpected chown error: %v expected: %v", err, os.ErrNotExist)
  707. }
  708. os.Remove(testFilePath)
  709. }
  710. _, err = httpd.RemoveUser(user, http.StatusOK)
  711. if err != nil {
  712. t.Errorf("unable to remove user: %v", err)
  713. }
  714. os.RemoveAll(user.GetHomeDir())
  715. }
  716. func TestChtimes(t *testing.T) {
  717. usePubKey := false
  718. user, _, err := httpd.AddUser(getTestUser(usePubKey), http.StatusOK)
  719. if err != nil {
  720. t.Errorf("unable to add user: %v", err)
  721. }
  722. client, err := getSftpClient(user, usePubKey)
  723. if err != nil {
  724. t.Errorf("unable to create sftp client: %v", err)
  725. } else {
  726. defer client.Close()
  727. testFileName := "test_file.dat"
  728. testFilePath := filepath.Join(homeBasePath, testFileName)
  729. testFileSize := int64(65535)
  730. testDir := "test"
  731. createTestFile(testFilePath, testFileSize)
  732. err = sftpUploadFile(testFilePath, testFileName, testFileSize, client)
  733. if err != nil {
  734. t.Errorf("file upload error: %v", err)
  735. }
  736. acmodTime := time.Now()
  737. err = client.Chtimes(testFileName, acmodTime, acmodTime)
  738. if err != nil {
  739. t.Errorf("error changing file times")
  740. }
  741. newFi, err := client.Lstat(testFileName)
  742. if err != nil {
  743. t.Errorf("file stat error: %v", err)
  744. }
  745. diff := math.Abs(newFi.ModTime().Sub(acmodTime).Seconds())
  746. if diff > 1 {
  747. t.Errorf("diff between wanted and real modification time too big: %v", diff)
  748. }
  749. err = client.Chtimes("invalidFile", acmodTime, acmodTime)
  750. if !os.IsNotExist(err) {
  751. t.Errorf("unexpected error: %v", err)
  752. }
  753. err = client.Mkdir(testDir)
  754. if err != nil {
  755. t.Errorf("unable to create dir: %v", err)
  756. }
  757. err = client.Chtimes(testDir, acmodTime, acmodTime)
  758. if err != nil {
  759. t.Errorf("error changing dir times")
  760. }
  761. newFi, err = client.Lstat(testDir)
  762. if err != nil {
  763. t.Errorf("dir stat error: %v", err)
  764. }
  765. diff = math.Abs(newFi.ModTime().Sub(acmodTime).Seconds())
  766. if diff > 1 {
  767. t.Errorf("diff between wanted and real modification time too big: %v", diff)
  768. }
  769. os.Remove(testFilePath)
  770. }
  771. _, err = httpd.RemoveUser(user, http.StatusOK)
  772. if err != nil {
  773. t.Errorf("unable to remove user: %v", err)
  774. }
  775. os.RemoveAll(user.GetHomeDir())
  776. }
  777. // basic tests to verify virtual chroot, should be improved to cover more cases ...
  778. func TestEscapeHomeDir(t *testing.T) {
  779. usePubKey := true
  780. user, _, err := httpd.AddUser(getTestUser(usePubKey), http.StatusOK)
  781. if err != nil {
  782. t.Errorf("unable to add user: %v", err)
  783. }
  784. client, err := getSftpClient(user, usePubKey)
  785. if err != nil {
  786. t.Errorf("unable to create sftp client: %v", err)
  787. } else {
  788. defer client.Close()
  789. _, err := client.Getwd()
  790. if err != nil {
  791. t.Errorf("unable to get working dir: %v", err)
  792. }
  793. testDir := "testDir"
  794. linkPath := filepath.Join(homeBasePath, defaultUsername, testDir)
  795. err = os.Symlink(homeBasePath, linkPath)
  796. if err != nil {
  797. t.Errorf("error making local symlink: %v", err)
  798. }
  799. _, err = client.ReadDir(testDir)
  800. if err == nil {
  801. t.Errorf("reading a symbolic link outside home dir should not succeeded")
  802. }
  803. os.Remove(linkPath)
  804. testFileName := "test_file.dat"
  805. testFilePath := filepath.Join(homeBasePath, testFileName)
  806. testFileSize := int64(65535)
  807. err = createTestFile(testFilePath, testFileSize)
  808. if err != nil {
  809. t.Errorf("unable to create test file: %v", err)
  810. }
  811. remoteDestPath := path.Join("..", "..", testFileName)
  812. err = sftpUploadFile(testFilePath, remoteDestPath, testFileSize, client)
  813. if err != nil {
  814. t.Errorf("file upload error: %v", err)
  815. }
  816. _, err = client.Lstat(testFileName)
  817. if err != nil {
  818. t.Errorf("file stat error: %v the file was created outside the user dir!", err)
  819. }
  820. err = client.Remove(testFileName)
  821. if err != nil {
  822. t.Errorf("error removing uploaded file: %v", err)
  823. }
  824. linkPath = filepath.Join(homeBasePath, defaultUsername, testFileName)
  825. err = os.Symlink(homeBasePath, linkPath)
  826. if err != nil {
  827. t.Errorf("error making local symlink: %v", err)
  828. }
  829. err = sftpDownloadFile(testFileName, testFilePath, 0, client)
  830. if err == nil {
  831. t.Errorf("download file outside home dir must fail")
  832. }
  833. err = sftpUploadFile(testFilePath, remoteDestPath, testFileSize, client)
  834. if err == nil {
  835. t.Errorf("overwrite a file outside home dir must fail")
  836. }
  837. err = client.Chmod(remoteDestPath, 0644)
  838. if err == nil {
  839. t.Errorf("setstat on a file outside home dir must fail")
  840. }
  841. os.Remove(linkPath)
  842. os.Remove(testFilePath)
  843. }
  844. _, err = httpd.RemoveUser(user, http.StatusOK)
  845. if err != nil {
  846. t.Errorf("unable to remove user: %v", err)
  847. }
  848. os.RemoveAll(user.GetHomeDir())
  849. }
  850. func TestHomeSpecialChars(t *testing.T) {
  851. usePubKey := true
  852. u := getTestUser(usePubKey)
  853. u.HomeDir = filepath.Join(homeBasePath, "abc açà#&%lk")
  854. user, _, err := httpd.AddUser(u, http.StatusOK)
  855. if err != nil {
  856. t.Errorf("unable to add user: %v", err)
  857. }
  858. client, err := getSftpClient(user, usePubKey)
  859. if err != nil {
  860. t.Errorf("unable to create sftp client: %v", err)
  861. } else {
  862. defer client.Close()
  863. _, err := client.Getwd()
  864. if err != nil {
  865. t.Errorf("unable to get working dir: %v", err)
  866. }
  867. testFileName := "test_file.dat"
  868. testFilePath := filepath.Join(homeBasePath, testFileName)
  869. testFileSize := int64(65535)
  870. err = createTestFile(testFilePath, testFileSize)
  871. if err != nil {
  872. t.Errorf("unable to create test file: %v", err)
  873. }
  874. err = sftpUploadFile(testFilePath, testFileName, testFileSize, client)
  875. if err != nil {
  876. t.Errorf("file upload error: %v", err)
  877. }
  878. files, err := client.ReadDir(".")
  879. if err != nil {
  880. t.Errorf("unable to read remote dir: %v", err)
  881. }
  882. if len(files) < 1 {
  883. t.Errorf("expected at least 1 file in this dir")
  884. }
  885. err = client.Remove(testFileName)
  886. if err != nil {
  887. t.Errorf("error removing uploaded file: %v", err)
  888. }
  889. os.Remove(testFilePath)
  890. }
  891. _, err = httpd.RemoveUser(user, http.StatusOK)
  892. if err != nil {
  893. t.Errorf("unable to remove user: %v", err)
  894. }
  895. os.RemoveAll(user.GetHomeDir())
  896. }
  897. func TestLogin(t *testing.T) {
  898. u := getTestUser(false)
  899. u.PublicKeys = []string{testPubKey}
  900. user, _, err := httpd.AddUser(u, http.StatusOK)
  901. if err != nil {
  902. t.Errorf("unable to add user: %v", err)
  903. }
  904. client, err := getSftpClient(user, false)
  905. if err != nil {
  906. t.Errorf("unable to create sftp client: %v", err)
  907. } else {
  908. defer client.Close()
  909. _, err := client.Getwd()
  910. if err != nil {
  911. t.Errorf("sftp client with valid password must work")
  912. }
  913. user, _, err = httpd.GetUserByID(user.ID, http.StatusOK)
  914. if err != nil {
  915. t.Errorf("error getting user: %v", err)
  916. }
  917. if user.LastLogin <= 0 {
  918. t.Errorf("last login must be updated after a successful login: %v", user.LastLogin)
  919. }
  920. }
  921. client, err = getSftpClient(user, true)
  922. if err != nil {
  923. t.Errorf("unable to create sftp client: %v", err)
  924. } else {
  925. defer client.Close()
  926. _, err := client.Getwd()
  927. if err != nil {
  928. t.Errorf("sftp client with valid public key must work")
  929. }
  930. }
  931. user.Password = "invalid password"
  932. client, err = getSftpClient(user, false)
  933. if err == nil {
  934. t.Errorf("login with invalid password must fail")
  935. defer client.Close()
  936. }
  937. // testPubKey1 is not authorized
  938. user.PublicKeys = []string{testPubKey1}
  939. user.Password = ""
  940. _, _, err = httpd.UpdateUser(user, http.StatusOK)
  941. if err != nil {
  942. t.Errorf("unable to update user: %v", err)
  943. }
  944. client, err = getSftpClient(user, true)
  945. if err == nil {
  946. t.Errorf("login with invalid public key must fail")
  947. defer client.Close()
  948. }
  949. // login a user with multiple public keys, only the second one is valid
  950. user.PublicKeys = []string{testPubKey1, testPubKey}
  951. user.Password = ""
  952. _, _, err = httpd.UpdateUser(user, http.StatusOK)
  953. if err != nil {
  954. t.Errorf("unable to update user: %v", err)
  955. }
  956. client, err = getSftpClient(user, true)
  957. if err != nil {
  958. t.Errorf("unable to create sftp client: %v", err)
  959. } else {
  960. defer client.Close()
  961. _, err := client.Getwd()
  962. if err != nil {
  963. t.Errorf("sftp client with multiple public key must work if at least one public key is valid")
  964. }
  965. }
  966. _, err = httpd.RemoveUser(user, http.StatusOK)
  967. if err != nil {
  968. t.Errorf("unable to remove user: %v", err)
  969. }
  970. os.RemoveAll(user.GetHomeDir())
  971. }
  972. func TestMultiStepLoginKeyAndPwd(t *testing.T) {
  973. u := getTestUser(true)
  974. u.Password = defaultPassword
  975. u.Filters.DeniedLoginMethods = append(u.Filters.DeniedLoginMethods, []string{
  976. dataprovider.SSHLoginMethodKeyAndKeyboardInt,
  977. dataprovider.SSHLoginMethodPublicKey,
  978. dataprovider.SSHLoginMethodPassword,
  979. dataprovider.SSHLoginMethodKeyboardInteractive,
  980. }...)
  981. user, _, err := httpd.AddUser(u, http.StatusOK)
  982. if err != nil {
  983. t.Errorf("unable to add user: %v", err)
  984. }
  985. _, err = getSftpClient(user, true)
  986. if err == nil {
  987. t.Error("login with public key is disallowed and must fail")
  988. }
  989. _, err = getSftpClient(user, true)
  990. if err == nil {
  991. t.Error("login with password is disallowed and must fail")
  992. }
  993. key, _ := ssh.ParsePrivateKey([]byte(testPrivateKey))
  994. authMethods := []ssh.AuthMethod{
  995. ssh.PublicKeys(key),
  996. ssh.Password(defaultPassword),
  997. }
  998. client, err := getCustomAuthSftpClient(user, authMethods)
  999. if err != nil {
  1000. t.Errorf("unable to create sftp client: %v", err)
  1001. } else {
  1002. defer client.Close()
  1003. _, err := client.Getwd()
  1004. if err != nil {
  1005. t.Errorf("unexpected error: %v", err)
  1006. }
  1007. }
  1008. authMethods = []ssh.AuthMethod{
  1009. ssh.Password(defaultPassword),
  1010. ssh.PublicKeys(key),
  1011. }
  1012. _, err = getCustomAuthSftpClient(user, authMethods)
  1013. if err == nil {
  1014. t.Error("multi step auth login with wrong order must fail")
  1015. }
  1016. _, err = httpd.RemoveUser(user, http.StatusOK)
  1017. if err != nil {
  1018. t.Errorf("unable to remove user: %v", err)
  1019. }
  1020. os.RemoveAll(user.GetHomeDir())
  1021. }
  1022. func TestMultiStepLoginKeyAndKeyInt(t *testing.T) {
  1023. if runtime.GOOS == "windows" {
  1024. t.Skip("this test is not available on Windows")
  1025. }
  1026. u := getTestUser(true)
  1027. u.Password = defaultPassword
  1028. u.Filters.DeniedLoginMethods = append(u.Filters.DeniedLoginMethods, []string{
  1029. dataprovider.SSHLoginMethodKeyAndPassword,
  1030. dataprovider.SSHLoginMethodPublicKey,
  1031. dataprovider.SSHLoginMethodPassword,
  1032. dataprovider.SSHLoginMethodKeyboardInteractive,
  1033. }...)
  1034. user, _, err := httpd.AddUser(u, http.StatusOK)
  1035. if err != nil {
  1036. t.Errorf("unable to add user: %v", err)
  1037. }
  1038. ioutil.WriteFile(keyIntAuthPath, getKeyboardInteractiveScriptContent([]string{"1", "2"}, 0, false, 1), 0755)
  1039. _, err = getSftpClient(user, true)
  1040. if err == nil {
  1041. t.Error("login with public key is disallowed and must fail")
  1042. }
  1043. key, _ := ssh.ParsePrivateKey([]byte(testPrivateKey))
  1044. authMethods := []ssh.AuthMethod{
  1045. ssh.PublicKeys(key),
  1046. ssh.KeyboardInteractive(func(user, instruction string, questions []string, echos []bool) ([]string, error) {
  1047. return []string{"1", "2"}, nil
  1048. }),
  1049. }
  1050. client, err := getCustomAuthSftpClient(user, authMethods)
  1051. if err != nil {
  1052. t.Errorf("unable to create sftp client: %v", err)
  1053. } else {
  1054. defer client.Close()
  1055. _, err := client.Getwd()
  1056. if err != nil {
  1057. t.Errorf("unexpected error: %v", err)
  1058. }
  1059. }
  1060. authMethods = []ssh.AuthMethod{
  1061. ssh.KeyboardInteractive(func(user, instruction string, questions []string, echos []bool) ([]string, error) {
  1062. return []string{"1", "2"}, nil
  1063. }),
  1064. ssh.PublicKeys(key),
  1065. }
  1066. _, err = getCustomAuthSftpClient(user, authMethods)
  1067. if err == nil {
  1068. t.Error("multi step auth login with wrong order must fail")
  1069. }
  1070. authMethods = []ssh.AuthMethod{
  1071. ssh.PublicKeys(key),
  1072. ssh.Password(defaultPassword),
  1073. }
  1074. _, err = getCustomAuthSftpClient(user, authMethods)
  1075. if err == nil {
  1076. t.Error("multi step auth login with wrong method must fail")
  1077. }
  1078. _, err = httpd.RemoveUser(user, http.StatusOK)
  1079. if err != nil {
  1080. t.Errorf("unable to remove user: %v", err)
  1081. }
  1082. os.RemoveAll(user.GetHomeDir())
  1083. }
  1084. func TestLoginUserStatus(t *testing.T) {
  1085. usePubKey := true
  1086. user, _, err := httpd.AddUser(getTestUser(usePubKey), http.StatusOK)
  1087. if err != nil {
  1088. t.Errorf("unable to add user: %v", err)
  1089. }
  1090. client, err := getSftpClient(user, usePubKey)
  1091. if err != nil {
  1092. t.Errorf("unable to create sftp client: %v", err)
  1093. } else {
  1094. defer client.Close()
  1095. _, err := client.Getwd()
  1096. if err != nil {
  1097. t.Errorf("sftp client with valid credentials must work")
  1098. }
  1099. user, _, err = httpd.GetUserByID(user.ID, http.StatusOK)
  1100. if err != nil {
  1101. t.Errorf("error getting user: %v", err)
  1102. }
  1103. if user.LastLogin <= 0 {
  1104. t.Errorf("last login must be updated after a successful login: %v", user.LastLogin)
  1105. }
  1106. }
  1107. user.Status = 0
  1108. user, _, err = httpd.UpdateUser(user, http.StatusOK)
  1109. if err != nil {
  1110. t.Errorf("unable to update user: %v", err)
  1111. }
  1112. client, err = getSftpClient(user, usePubKey)
  1113. if err == nil {
  1114. t.Errorf("login for a disabled user must fail")
  1115. defer client.Close()
  1116. }
  1117. _, err = httpd.RemoveUser(user, http.StatusOK)
  1118. if err != nil {
  1119. t.Errorf("unable to remove user: %v", err)
  1120. }
  1121. os.RemoveAll(user.GetHomeDir())
  1122. }
  1123. func TestLoginUserExpiration(t *testing.T) {
  1124. usePubKey := true
  1125. user, _, err := httpd.AddUser(getTestUser(usePubKey), http.StatusOK)
  1126. if err != nil {
  1127. t.Errorf("unable to add user: %v", err)
  1128. }
  1129. client, err := getSftpClient(user, usePubKey)
  1130. if err != nil {
  1131. t.Errorf("unable to create sftp client: %v", err)
  1132. } else {
  1133. defer client.Close()
  1134. _, err := client.Getwd()
  1135. if err != nil {
  1136. t.Errorf("sftp client with valid credentials must work")
  1137. }
  1138. user, _, err = httpd.GetUserByID(user.ID, http.StatusOK)
  1139. if err != nil {
  1140. t.Errorf("error getting user: %v", err)
  1141. }
  1142. if user.LastLogin <= 0 {
  1143. t.Errorf("last login must be updated after a successful login: %v", user.LastLogin)
  1144. }
  1145. }
  1146. user.ExpirationDate = utils.GetTimeAsMsSinceEpoch(time.Now()) - 120000
  1147. user, _, err = httpd.UpdateUser(user, http.StatusOK)
  1148. if err != nil {
  1149. t.Errorf("unable to update user: %v", err)
  1150. }
  1151. client, err = getSftpClient(user, usePubKey)
  1152. if err == nil {
  1153. t.Errorf("login for an expired user must fail")
  1154. defer client.Close()
  1155. }
  1156. user.ExpirationDate = utils.GetTimeAsMsSinceEpoch(time.Now()) + 120000
  1157. _, _, err = httpd.UpdateUser(user, http.StatusOK)
  1158. if err != nil {
  1159. t.Errorf("unable to update user: %v", err)
  1160. }
  1161. client, err = getSftpClient(user, usePubKey)
  1162. if err != nil {
  1163. t.Errorf("login for a non expired user must succeed: %v", err)
  1164. } else {
  1165. defer client.Close()
  1166. }
  1167. _, err = httpd.RemoveUser(user, http.StatusOK)
  1168. if err != nil {
  1169. t.Errorf("unable to remove user: %v", err)
  1170. }
  1171. os.RemoveAll(user.GetHomeDir())
  1172. }
  1173. func TestLoginInvalidFs(t *testing.T) {
  1174. if runtime.GOOS == "windows" {
  1175. t.Skip("this test is not available on Windows")
  1176. }
  1177. config.LoadConfig(configDir, "")
  1178. providerConf := config.GetProviderConf()
  1179. if providerConf.Driver != dataprovider.SQLiteDataProviderName {
  1180. t.Skip("this test require sqlite provider")
  1181. }
  1182. dbPath := providerConf.Name
  1183. if !filepath.IsAbs(dbPath) {
  1184. dbPath = filepath.Join(configDir, dbPath)
  1185. }
  1186. usePubKey := true
  1187. u := getTestUser(usePubKey)
  1188. user, _, err := httpd.AddUser(u, http.StatusOK)
  1189. if err != nil {
  1190. t.Errorf("unable to add user: %v", err)
  1191. }
  1192. // we update the database using sqlite3 CLI since we cannot add a user with an invalid config
  1193. time.Sleep(200 * time.Millisecond)
  1194. updateUserQuery := fmt.Sprintf("UPDATE users SET filesystem='{\"provider\":1}' WHERE id=%v", user.ID)
  1195. cmd := exec.Command("sqlite3", dbPath, updateUserQuery)
  1196. out, err := cmd.CombinedOutput()
  1197. if err != nil {
  1198. t.Errorf("unexpected error: %v, cmd out: %v", err, string(out))
  1199. }
  1200. time.Sleep(200 * time.Millisecond)
  1201. _, err = getSftpClient(user, usePubKey)
  1202. if err == nil {
  1203. t.Error("login must fail, the user has an invalid filesystem config")
  1204. }
  1205. _, err = httpd.RemoveUser(user, http.StatusOK)
  1206. if err != nil {
  1207. t.Errorf("unable to remove user: %v", err)
  1208. }
  1209. os.RemoveAll(user.GetHomeDir())
  1210. }
  1211. func TestDeniedLoginMethods(t *testing.T) {
  1212. u := getTestUser(true)
  1213. u.Filters.DeniedLoginMethods = []string{dataprovider.SSHLoginMethodPublicKey, dataprovider.SSHLoginMethodPassword}
  1214. user, _, err := httpd.AddUser(u, http.StatusOK)
  1215. if err != nil {
  1216. t.Errorf("unable to add user: %v", err)
  1217. }
  1218. _, err = getSftpClient(user, true)
  1219. if err == nil {
  1220. t.Error("public key login is disabled, authentication must fail")
  1221. }
  1222. user.Filters.DeniedLoginMethods = []string{dataprovider.SSHLoginMethodKeyboardInteractive, dataprovider.SSHLoginMethodPassword}
  1223. user, _, err = httpd.UpdateUser(user, http.StatusOK)
  1224. if err != nil {
  1225. t.Errorf("unable to update user: %v", err)
  1226. }
  1227. client, err := getSftpClient(user, true)
  1228. if err != nil {
  1229. t.Errorf("unable to create sftp client: %v", err)
  1230. } else {
  1231. client.Close()
  1232. }
  1233. user.Password = defaultPassword
  1234. user, _, err = httpd.UpdateUser(user, http.StatusOK)
  1235. if err != nil {
  1236. t.Errorf("unable to update user: %v", err)
  1237. }
  1238. _, err = getSftpClient(user, false)
  1239. if err == nil {
  1240. t.Error("password login is disabled, authentication must fail")
  1241. }
  1242. user.Filters.DeniedLoginMethods = []string{dataprovider.SSHLoginMethodKeyboardInteractive, dataprovider.SSHLoginMethodPublicKey}
  1243. user, _, err = httpd.UpdateUser(user, http.StatusOK)
  1244. if err != nil {
  1245. t.Errorf("unable to update user: %v", err)
  1246. }
  1247. client, err = getSftpClient(user, false)
  1248. if err != nil {
  1249. t.Errorf("unable to create sftp client: %v", err)
  1250. } else {
  1251. client.Close()
  1252. }
  1253. _, err = httpd.RemoveUser(user, http.StatusOK)
  1254. if err != nil {
  1255. t.Errorf("unable to remove user: %v", err)
  1256. }
  1257. os.RemoveAll(user.GetHomeDir())
  1258. }
  1259. func TestLoginWithIPFilters(t *testing.T) {
  1260. usePubKey := true
  1261. u := getTestUser(usePubKey)
  1262. u.Filters.DeniedIP = []string{"192.167.0.0/24", "172.18.0.0/16"}
  1263. u.Filters.AllowedIP = []string{}
  1264. user, _, err := httpd.AddUser(u, http.StatusOK)
  1265. if err != nil {
  1266. t.Errorf("unable to add user: %v", err)
  1267. }
  1268. client, err := getSftpClient(user, usePubKey)
  1269. if err != nil {
  1270. t.Errorf("unable to create sftp client: %v", err)
  1271. } else {
  1272. defer client.Close()
  1273. _, err := client.Getwd()
  1274. if err != nil {
  1275. t.Errorf("sftp client with valid credentials must work")
  1276. }
  1277. user, _, err = httpd.GetUserByID(user.ID, http.StatusOK)
  1278. if err != nil {
  1279. t.Errorf("error getting user: %v", err)
  1280. }
  1281. if user.LastLogin <= 0 {
  1282. t.Errorf("last login must be updated after a successful login: %v", user.LastLogin)
  1283. }
  1284. }
  1285. user.Filters.AllowedIP = []string{"127.0.0.0/8"}
  1286. _, _, err = httpd.UpdateUser(user, http.StatusOK)
  1287. if err != nil {
  1288. t.Errorf("unable to update user: %v", err)
  1289. }
  1290. client, err = getSftpClient(user, usePubKey)
  1291. if err != nil {
  1292. t.Errorf("login from an allowed IP must succeed: %v", err)
  1293. } else {
  1294. defer client.Close()
  1295. }
  1296. user.Filters.AllowedIP = []string{"172.19.0.0/16"}
  1297. _, _, err = httpd.UpdateUser(user, http.StatusOK)
  1298. if err != nil {
  1299. t.Errorf("unable to update user: %v", err)
  1300. }
  1301. client, err = getSftpClient(user, usePubKey)
  1302. if err == nil {
  1303. t.Errorf("login from an not allowed IP must fail")
  1304. client.Close()
  1305. }
  1306. _, err = httpd.RemoveUser(user, http.StatusOK)
  1307. if err != nil {
  1308. t.Errorf("unable to remove user: %v", err)
  1309. }
  1310. os.RemoveAll(user.GetHomeDir())
  1311. }
  1312. func TestLoginAfterUserUpdateEmptyPwd(t *testing.T) {
  1313. usePubKey := false
  1314. user, _, err := httpd.AddUser(getTestUser(usePubKey), http.StatusOK)
  1315. if err != nil {
  1316. t.Errorf("unable to add user: %v", err)
  1317. }
  1318. user.Password = ""
  1319. user.PublicKeys = []string{}
  1320. // password and public key should remain unchanged
  1321. _, _, err = httpd.UpdateUser(user, http.StatusOK)
  1322. if err != nil {
  1323. t.Errorf("unable to update user: %v", err)
  1324. }
  1325. client, err := getSftpClient(user, usePubKey)
  1326. if err != nil {
  1327. t.Errorf("unable to create sftp client: %v", err)
  1328. } else {
  1329. defer client.Close()
  1330. _, err := client.Getwd()
  1331. if err != nil {
  1332. t.Errorf("unable to get working dir: %v", err)
  1333. }
  1334. _, err = client.ReadDir(".")
  1335. if err != nil {
  1336. t.Errorf("unable to read remote dir: %v", err)
  1337. }
  1338. }
  1339. _, err = httpd.RemoveUser(user, http.StatusOK)
  1340. if err != nil {
  1341. t.Errorf("unable to remove user: %v", err)
  1342. }
  1343. os.RemoveAll(user.GetHomeDir())
  1344. }
  1345. func TestLoginAfterUserUpdateEmptyPubKey(t *testing.T) {
  1346. usePubKey := true
  1347. user, _, err := httpd.AddUser(getTestUser(usePubKey), http.StatusOK)
  1348. if err != nil {
  1349. t.Errorf("unable to add user: %v", err)
  1350. }
  1351. user.Password = ""
  1352. user.PublicKeys = []string{}
  1353. // password and public key should remain unchanged
  1354. _, _, err = httpd.UpdateUser(user, http.StatusOK)
  1355. if err != nil {
  1356. t.Errorf("unable to update user: %v", err)
  1357. }
  1358. client, err := getSftpClient(user, usePubKey)
  1359. if err != nil {
  1360. t.Errorf("unable to create sftp client: %v", err)
  1361. } else {
  1362. defer client.Close()
  1363. _, err := client.Getwd()
  1364. if err != nil {
  1365. t.Errorf("unable to get working dir: %v", err)
  1366. }
  1367. _, err = client.ReadDir(".")
  1368. if err != nil {
  1369. t.Errorf("unable to read remote dir: %v", err)
  1370. }
  1371. }
  1372. _, err = httpd.RemoveUser(user, http.StatusOK)
  1373. if err != nil {
  1374. t.Errorf("unable to remove user: %v", err)
  1375. }
  1376. os.RemoveAll(user.GetHomeDir())
  1377. }
  1378. func TestLoginKeyboardInteractiveAuth(t *testing.T) {
  1379. if runtime.GOOS == "windows" {
  1380. t.Skip("this test is not available on Windows")
  1381. }
  1382. user, _, err := httpd.AddUser(getTestUser(false), http.StatusOK)
  1383. if err != nil {
  1384. t.Errorf("unable to add user: %v", err)
  1385. }
  1386. ioutil.WriteFile(keyIntAuthPath, getKeyboardInteractiveScriptContent([]string{"1", "2"}, 0, false, 1), 0755)
  1387. client, err := getKeyboardInteractiveSftpClient(user, []string{"1", "2"})
  1388. if err != nil {
  1389. t.Errorf("unable to create sftp client: %v", err)
  1390. } else {
  1391. defer client.Close()
  1392. _, err := client.Getwd()
  1393. if err != nil {
  1394. t.Errorf("unable to get working dir: %v", err)
  1395. }
  1396. _, err = client.ReadDir(".")
  1397. if err != nil {
  1398. t.Errorf("unable to read remote dir: %v", err)
  1399. }
  1400. }
  1401. user.Status = 0
  1402. user, _, err = httpd.UpdateUser(user, http.StatusOK)
  1403. if err != nil {
  1404. t.Errorf("error updating user: %v", err)
  1405. }
  1406. client, err = getKeyboardInteractiveSftpClient(user, []string{"1", "2"})
  1407. if err == nil {
  1408. t.Error("keyboard interactive auth must fail the user is disabled")
  1409. }
  1410. user.Status = 1
  1411. user, _, err = httpd.UpdateUser(user, http.StatusOK)
  1412. if err != nil {
  1413. t.Errorf("error updating user: %v", err)
  1414. }
  1415. ioutil.WriteFile(keyIntAuthPath, getKeyboardInteractiveScriptContent([]string{"1", "2"}, 0, false, -1), 0755)
  1416. client, err = getKeyboardInteractiveSftpClient(user, []string{"1", "2"})
  1417. if err == nil {
  1418. t.Error("keyboard interactive auth must fail the script returned -1")
  1419. }
  1420. ioutil.WriteFile(keyIntAuthPath, getKeyboardInteractiveScriptContent([]string{"1", "2"}, 0, true, 1), 0755)
  1421. client, err = getKeyboardInteractiveSftpClient(user, []string{"1", "2"})
  1422. if err == nil {
  1423. t.Error("keyboard interactive auth must fail the script returned bad json")
  1424. }
  1425. ioutil.WriteFile(keyIntAuthPath, getKeyboardInteractiveScriptContent([]string{"1", "2"}, 5, true, 1), 0755)
  1426. client, err = getKeyboardInteractiveSftpClient(user, []string{"1", "2"})
  1427. if err == nil {
  1428. t.Error("keyboard interactive auth must fail the script returned bad json")
  1429. }
  1430. _, err = httpd.RemoveUser(user, http.StatusOK)
  1431. if err != nil {
  1432. t.Errorf("unable to remove user: %v", err)
  1433. }
  1434. os.RemoveAll(user.GetHomeDir())
  1435. }
  1436. func TestPreLoginScript(t *testing.T) {
  1437. if runtime.GOOS == "windows" {
  1438. t.Skip("this test is not available on Windows")
  1439. }
  1440. usePubKey := true
  1441. u := getTestUser(usePubKey)
  1442. dataProvider := dataprovider.GetProvider()
  1443. dataprovider.Close(dataProvider)
  1444. config.LoadConfig(configDir, "")
  1445. providerConf := config.GetProviderConf()
  1446. ioutil.WriteFile(preLoginPath, getPreLoginScriptContent(u, false), 0755)
  1447. providerConf.PreLoginHook = preLoginPath
  1448. err := dataprovider.Initialize(providerConf, configDir)
  1449. if err != nil {
  1450. t.Errorf("error initializing data provider")
  1451. }
  1452. httpd.SetDataProvider(dataprovider.GetProvider())
  1453. sftpd.SetDataProvider(dataprovider.GetProvider())
  1454. user, _, err := httpd.AddUser(u, http.StatusOK)
  1455. if err != nil {
  1456. t.Errorf("unable to add user: %v", err)
  1457. }
  1458. client, err := getSftpClient(u, usePubKey)
  1459. if err != nil {
  1460. t.Errorf("unable to create sftp client: %v", err)
  1461. } else {
  1462. defer client.Close()
  1463. _, err = client.Getwd()
  1464. if err != nil {
  1465. t.Errorf("unable to get working dir: %v", err)
  1466. }
  1467. }
  1468. ioutil.WriteFile(preLoginPath, getPreLoginScriptContent(user, true), 0755)
  1469. _, err = getSftpClient(u, usePubKey)
  1470. if err == nil {
  1471. t.Error("pre-login script returned a non json response, login must fail")
  1472. }
  1473. user.Status = 0
  1474. ioutil.WriteFile(preLoginPath, getPreLoginScriptContent(user, false), 0755)
  1475. _, err = getSftpClient(u, usePubKey)
  1476. if err == nil {
  1477. t.Error("pre-login script returned a disabled user, login must fail")
  1478. }
  1479. _, err = httpd.RemoveUser(user, http.StatusOK)
  1480. if err != nil {
  1481. t.Errorf("unable to remove user: %v", err)
  1482. }
  1483. os.RemoveAll(user.GetHomeDir())
  1484. dataProvider = dataprovider.GetProvider()
  1485. dataprovider.Close(dataProvider)
  1486. config.LoadConfig(configDir, "")
  1487. providerConf = config.GetProviderConf()
  1488. err = dataprovider.Initialize(providerConf, configDir)
  1489. if err != nil {
  1490. t.Errorf("error initializing data provider")
  1491. }
  1492. httpd.SetDataProvider(dataprovider.GetProvider())
  1493. sftpd.SetDataProvider(dataprovider.GetProvider())
  1494. os.Remove(preLoginPath)
  1495. }
  1496. func TestPreLoginUserCreation(t *testing.T) {
  1497. if runtime.GOOS == "windows" {
  1498. t.Skip("this test is not available on Windows")
  1499. }
  1500. usePubKey := false
  1501. u := getTestUser(usePubKey)
  1502. dataProvider := dataprovider.GetProvider()
  1503. dataprovider.Close(dataProvider)
  1504. config.LoadConfig(configDir, "")
  1505. providerConf := config.GetProviderConf()
  1506. ioutil.WriteFile(preLoginPath, getPreLoginScriptContent(u, false), 0755)
  1507. providerConf.PreLoginHook = preLoginPath
  1508. err := dataprovider.Initialize(providerConf, configDir)
  1509. if err != nil {
  1510. t.Errorf("error initializing data provider")
  1511. }
  1512. httpd.SetDataProvider(dataprovider.GetProvider())
  1513. sftpd.SetDataProvider(dataprovider.GetProvider())
  1514. users, out, err := httpd.GetUsers(0, 0, defaultUsername, http.StatusOK)
  1515. if err != nil {
  1516. t.Errorf("unable to get users: %v, out: %v", err, string(out))
  1517. }
  1518. if len(users) != 0 {
  1519. t.Errorf("number of users mismatch, expected: 0, actual: %v", len(users))
  1520. }
  1521. client, err := getSftpClient(u, usePubKey)
  1522. if err != nil {
  1523. t.Errorf("unable to create sftp client: %v", err)
  1524. } else {
  1525. defer client.Close()
  1526. _, err = client.Getwd()
  1527. if err != nil {
  1528. t.Errorf("unable to get working dir: %v", err)
  1529. }
  1530. }
  1531. users, out, err = httpd.GetUsers(0, 0, defaultUsername, http.StatusOK)
  1532. if err != nil {
  1533. t.Errorf("unable to get users: %v, out: %v", err, string(out))
  1534. }
  1535. if len(users) != 1 {
  1536. t.Errorf("number of users mismatch, expected: 1, actual: %v", len(users))
  1537. }
  1538. user := users[0]
  1539. os.RemoveAll(user.GetHomeDir())
  1540. dataProvider = dataprovider.GetProvider()
  1541. dataprovider.Close(dataProvider)
  1542. config.LoadConfig(configDir, "")
  1543. providerConf = config.GetProviderConf()
  1544. err = dataprovider.Initialize(providerConf, configDir)
  1545. if err != nil {
  1546. t.Errorf("error initializing data provider")
  1547. }
  1548. httpd.SetDataProvider(dataprovider.GetProvider())
  1549. sftpd.SetDataProvider(dataprovider.GetProvider())
  1550. os.Remove(preLoginPath)
  1551. }
  1552. func TestLoginExternalAuthPwdAndPubKey(t *testing.T) {
  1553. if runtime.GOOS == "windows" {
  1554. t.Skip("this test is not available on Windows")
  1555. }
  1556. usePubKey := true
  1557. u := getTestUser(usePubKey)
  1558. u.QuotaFiles = 1000
  1559. dataProvider := dataprovider.GetProvider()
  1560. dataprovider.Close(dataProvider)
  1561. config.LoadConfig(configDir, "")
  1562. providerConf := config.GetProviderConf()
  1563. ioutil.WriteFile(extAuthPath, getExtAuthScriptContent(u, 0, false), 0755)
  1564. providerConf.ExternalAuthHook = extAuthPath
  1565. providerConf.ExternalAuthScope = 0
  1566. err := dataprovider.Initialize(providerConf, configDir)
  1567. if err != nil {
  1568. t.Errorf("error initializing data provider")
  1569. }
  1570. httpd.SetDataProvider(dataprovider.GetProvider())
  1571. sftpd.SetDataProvider(dataprovider.GetProvider())
  1572. client, err := getSftpClient(u, usePubKey)
  1573. if err != nil {
  1574. t.Errorf("unable to create sftp client: %v", err)
  1575. } else {
  1576. defer client.Close()
  1577. testFileName := "test_file.dat"
  1578. testFilePath := filepath.Join(homeBasePath, testFileName)
  1579. testFileSize := int64(65535)
  1580. err = createTestFile(testFilePath, testFileSize)
  1581. if err != nil {
  1582. t.Errorf("unable to create test file: %v", err)
  1583. }
  1584. err = sftpUploadFile(testFilePath, testFileName, testFileSize, client)
  1585. if err != nil {
  1586. t.Errorf("file upload error: %v", err)
  1587. }
  1588. os.Remove(testFilePath)
  1589. }
  1590. u.Username = defaultUsername + "1"
  1591. client, err = getSftpClient(u, usePubKey)
  1592. if err == nil {
  1593. t.Error("external auth login with invalid user must fail")
  1594. }
  1595. usePubKey = false
  1596. u = getTestUser(usePubKey)
  1597. u.PublicKeys = []string{}
  1598. ioutil.WriteFile(extAuthPath, getExtAuthScriptContent(u, 0, false), 0755)
  1599. client, err = getSftpClient(u, usePubKey)
  1600. if err != nil {
  1601. t.Errorf("unable to create sftp client: %v", err)
  1602. } else {
  1603. defer client.Close()
  1604. _, err := client.Getwd()
  1605. if err != nil {
  1606. t.Errorf("unable to get working dir: %v", err)
  1607. }
  1608. }
  1609. users, out, err := httpd.GetUsers(0, 0, defaultUsername, http.StatusOK)
  1610. if err != nil {
  1611. t.Errorf("unable to get users: %v, out: %v", err, string(out))
  1612. }
  1613. if len(users) != 1 {
  1614. t.Errorf("number of users mismatch, expected: 1, actual: %v", len(users))
  1615. }
  1616. user := users[0]
  1617. if len(user.PublicKeys) != 0 {
  1618. t.Errorf("number of public keys mismatch, expected: 0, actual: %v", len(user.PublicKeys))
  1619. }
  1620. if user.UsedQuotaSize == 0 {
  1621. t.Error("quota size must be > 0")
  1622. }
  1623. _, err = httpd.RemoveUser(user, http.StatusOK)
  1624. if err != nil {
  1625. t.Errorf("unable to remove: %v", err)
  1626. }
  1627. os.RemoveAll(user.GetHomeDir())
  1628. dataProvider = dataprovider.GetProvider()
  1629. dataprovider.Close(dataProvider)
  1630. config.LoadConfig(configDir, "")
  1631. providerConf = config.GetProviderConf()
  1632. err = dataprovider.Initialize(providerConf, configDir)
  1633. if err != nil {
  1634. t.Errorf("error initializing data provider")
  1635. }
  1636. httpd.SetDataProvider(dataprovider.GetProvider())
  1637. sftpd.SetDataProvider(dataprovider.GetProvider())
  1638. os.Remove(extAuthPath)
  1639. }
  1640. func TestLoginExternalAuthPwd(t *testing.T) {
  1641. if runtime.GOOS == "windows" {
  1642. t.Skip("this test is not available on Windows")
  1643. }
  1644. usePubKey := false
  1645. u := getTestUser(usePubKey)
  1646. dataProvider := dataprovider.GetProvider()
  1647. dataprovider.Close(dataProvider)
  1648. config.LoadConfig(configDir, "")
  1649. providerConf := config.GetProviderConf()
  1650. ioutil.WriteFile(extAuthPath, getExtAuthScriptContent(u, 0, false), 0755)
  1651. providerConf.ExternalAuthHook = extAuthPath
  1652. providerConf.ExternalAuthScope = 1
  1653. err := dataprovider.Initialize(providerConf, configDir)
  1654. if err != nil {
  1655. t.Errorf("error initializing data provider")
  1656. }
  1657. httpd.SetDataProvider(dataprovider.GetProvider())
  1658. sftpd.SetDataProvider(dataprovider.GetProvider())
  1659. client, err := getSftpClient(u, usePubKey)
  1660. if err != nil {
  1661. t.Errorf("unable to create sftp client: %v", err)
  1662. } else {
  1663. defer client.Close()
  1664. _, err := client.Getwd()
  1665. if err != nil {
  1666. t.Errorf("unable to get working dir: %v", err)
  1667. }
  1668. }
  1669. u.Username = defaultUsername + "1"
  1670. client, err = getSftpClient(u, usePubKey)
  1671. if err == nil {
  1672. t.Error("external auth login with invalid user must fail")
  1673. }
  1674. usePubKey = true
  1675. u = getTestUser(usePubKey)
  1676. client, err = getSftpClient(u, usePubKey)
  1677. if err == nil {
  1678. t.Error("external auth login with valid user but invalid auth scope must fail")
  1679. }
  1680. users, out, err := httpd.GetUsers(0, 0, defaultUsername, http.StatusOK)
  1681. if err != nil {
  1682. t.Errorf("unable to get users: %v, out: %v", err, string(out))
  1683. }
  1684. if len(users) != 1 {
  1685. t.Errorf("number of users mismatch, expected: 1, actual: %v", len(users))
  1686. }
  1687. user := users[0]
  1688. _, err = httpd.RemoveUser(user, http.StatusOK)
  1689. if err != nil {
  1690. t.Errorf("unable to remove: %v", err)
  1691. }
  1692. os.RemoveAll(user.GetHomeDir())
  1693. dataProvider = dataprovider.GetProvider()
  1694. dataprovider.Close(dataProvider)
  1695. config.LoadConfig(configDir, "")
  1696. providerConf = config.GetProviderConf()
  1697. err = dataprovider.Initialize(providerConf, configDir)
  1698. if err != nil {
  1699. t.Errorf("error initializing data provider")
  1700. }
  1701. httpd.SetDataProvider(dataprovider.GetProvider())
  1702. sftpd.SetDataProvider(dataprovider.GetProvider())
  1703. os.Remove(extAuthPath)
  1704. }
  1705. func TestLoginExternalAuthPubKey(t *testing.T) {
  1706. if runtime.GOOS == "windows" {
  1707. t.Skip("this test is not available on Windows")
  1708. }
  1709. usePubKey := true
  1710. u := getTestUser(usePubKey)
  1711. dataProvider := dataprovider.GetProvider()
  1712. dataprovider.Close(dataProvider)
  1713. config.LoadConfig(configDir, "")
  1714. providerConf := config.GetProviderConf()
  1715. ioutil.WriteFile(extAuthPath, getExtAuthScriptContent(u, 0, false), 0755)
  1716. providerConf.ExternalAuthHook = extAuthPath
  1717. providerConf.ExternalAuthScope = 2
  1718. err := dataprovider.Initialize(providerConf, configDir)
  1719. if err != nil {
  1720. t.Errorf("error initializing data provider")
  1721. }
  1722. httpd.SetDataProvider(dataprovider.GetProvider())
  1723. sftpd.SetDataProvider(dataprovider.GetProvider())
  1724. client, err := getSftpClient(u, usePubKey)
  1725. if err != nil {
  1726. t.Errorf("unable to create sftp client: %v", err)
  1727. } else {
  1728. defer client.Close()
  1729. _, err := client.Getwd()
  1730. if err != nil {
  1731. t.Errorf("unable to get working dir: %v", err)
  1732. }
  1733. }
  1734. u.Username = defaultUsername + "1"
  1735. client, err = getSftpClient(u, usePubKey)
  1736. if err == nil {
  1737. t.Error("external auth login with invalid user must fail")
  1738. }
  1739. usePubKey = false
  1740. u = getTestUser(usePubKey)
  1741. client, err = getSftpClient(u, usePubKey)
  1742. if err == nil {
  1743. t.Error("external auth login with valid user but invalid auth scope must fail")
  1744. }
  1745. users, out, err := httpd.GetUsers(0, 0, defaultUsername, http.StatusOK)
  1746. if err != nil {
  1747. t.Errorf("unable to get users: %v, out: %v", err, string(out))
  1748. }
  1749. if len(users) != 1 {
  1750. t.Errorf("number of users mismatch, expected: 1, actual: %v", len(users))
  1751. }
  1752. user := users[0]
  1753. _, err = httpd.RemoveUser(user, http.StatusOK)
  1754. if err != nil {
  1755. t.Errorf("unable to remove: %v", err)
  1756. }
  1757. os.RemoveAll(user.GetHomeDir())
  1758. dataProvider = dataprovider.GetProvider()
  1759. dataprovider.Close(dataProvider)
  1760. config.LoadConfig(configDir, "")
  1761. providerConf = config.GetProviderConf()
  1762. err = dataprovider.Initialize(providerConf, configDir)
  1763. if err != nil {
  1764. t.Errorf("error initializing data provider")
  1765. }
  1766. httpd.SetDataProvider(dataprovider.GetProvider())
  1767. sftpd.SetDataProvider(dataprovider.GetProvider())
  1768. os.Remove(extAuthPath)
  1769. }
  1770. func TestLoginExternalAuthInteractive(t *testing.T) {
  1771. if runtime.GOOS == "windows" {
  1772. t.Skip("this test is not available on Windows")
  1773. }
  1774. usePubKey := false
  1775. u := getTestUser(usePubKey)
  1776. dataProvider := dataprovider.GetProvider()
  1777. dataprovider.Close(dataProvider)
  1778. config.LoadConfig(configDir, "")
  1779. providerConf := config.GetProviderConf()
  1780. ioutil.WriteFile(extAuthPath, getExtAuthScriptContent(u, 0, false), 0755)
  1781. providerConf.ExternalAuthHook = extAuthPath
  1782. providerConf.ExternalAuthScope = 4
  1783. err := dataprovider.Initialize(providerConf, configDir)
  1784. if err != nil {
  1785. t.Errorf("error initializing data provider")
  1786. }
  1787. httpd.SetDataProvider(dataprovider.GetProvider())
  1788. sftpd.SetDataProvider(dataprovider.GetProvider())
  1789. ioutil.WriteFile(keyIntAuthPath, getKeyboardInteractiveScriptContent([]string{"1", "2"}, 0, false, 1), 0755)
  1790. client, err := getKeyboardInteractiveSftpClient(u, []string{"1", "2"})
  1791. if err != nil {
  1792. t.Errorf("unable to create sftp client: %v", err)
  1793. } else {
  1794. defer client.Close()
  1795. _, err := client.Getwd()
  1796. if err != nil {
  1797. t.Errorf("unable to get working dir: %v", err)
  1798. }
  1799. }
  1800. u.Username = defaultUsername + "1"
  1801. client, err = getKeyboardInteractiveSftpClient(u, []string{"1", "2"})
  1802. if err == nil {
  1803. t.Error("external auth login with invalid user must fail")
  1804. }
  1805. usePubKey = true
  1806. u = getTestUser(usePubKey)
  1807. client, err = getSftpClient(u, usePubKey)
  1808. if err == nil {
  1809. t.Error("external auth login with valid user but invalid auth scope must fail")
  1810. }
  1811. users, out, err := httpd.GetUsers(0, 0, defaultUsername, http.StatusOK)
  1812. if err != nil {
  1813. t.Errorf("unable to get users: %v, out: %v", err, string(out))
  1814. }
  1815. if len(users) != 1 {
  1816. t.Errorf("number of users mismatch, expected: 1, actual: %v", len(users))
  1817. }
  1818. user := users[0]
  1819. _, err = httpd.RemoveUser(user, http.StatusOK)
  1820. if err != nil {
  1821. t.Errorf("unable to remove: %v", err)
  1822. }
  1823. os.RemoveAll(user.GetHomeDir())
  1824. dataProvider = dataprovider.GetProvider()
  1825. dataprovider.Close(dataProvider)
  1826. config.LoadConfig(configDir, "")
  1827. providerConf = config.GetProviderConf()
  1828. err = dataprovider.Initialize(providerConf, configDir)
  1829. if err != nil {
  1830. t.Errorf("error initializing data provider")
  1831. }
  1832. httpd.SetDataProvider(dataprovider.GetProvider())
  1833. sftpd.SetDataProvider(dataprovider.GetProvider())
  1834. os.Remove(extAuthPath)
  1835. }
  1836. func TestLoginExternalAuthErrors(t *testing.T) {
  1837. if runtime.GOOS == "windows" {
  1838. t.Skip("this test is not available on Windows")
  1839. }
  1840. usePubKey := true
  1841. u := getTestUser(usePubKey)
  1842. dataProvider := dataprovider.GetProvider()
  1843. dataprovider.Close(dataProvider)
  1844. config.LoadConfig(configDir, "")
  1845. providerConf := config.GetProviderConf()
  1846. ioutil.WriteFile(extAuthPath, getExtAuthScriptContent(u, 0, true), 0755)
  1847. providerConf.ExternalAuthHook = extAuthPath
  1848. providerConf.ExternalAuthScope = 0
  1849. err := dataprovider.Initialize(providerConf, configDir)
  1850. if err != nil {
  1851. t.Errorf("error initializing data provider")
  1852. }
  1853. httpd.SetDataProvider(dataprovider.GetProvider())
  1854. sftpd.SetDataProvider(dataprovider.GetProvider())
  1855. _, err = getSftpClient(u, usePubKey)
  1856. if err == nil {
  1857. t.Error("login must fail, external auth returns a non json response")
  1858. }
  1859. usePubKey = false
  1860. u = getTestUser(usePubKey)
  1861. _, err = getSftpClient(u, usePubKey)
  1862. if err == nil {
  1863. t.Error("login must fail, external auth returns a non json response")
  1864. }
  1865. users, out, err := httpd.GetUsers(0, 0, defaultUsername, http.StatusOK)
  1866. if err != nil {
  1867. t.Errorf("unable to get users: %v, out: %v", err, string(out))
  1868. }
  1869. if len(users) != 0 {
  1870. t.Errorf("number of users mismatch, expected: 0, actual: %v", len(users))
  1871. }
  1872. dataProvider = dataprovider.GetProvider()
  1873. dataprovider.Close(dataProvider)
  1874. config.LoadConfig(configDir, "")
  1875. providerConf = config.GetProviderConf()
  1876. err = dataprovider.Initialize(providerConf, configDir)
  1877. if err != nil {
  1878. t.Errorf("error initializing data provider")
  1879. }
  1880. httpd.SetDataProvider(dataprovider.GetProvider())
  1881. sftpd.SetDataProvider(dataprovider.GetProvider())
  1882. os.Remove(extAuthPath)
  1883. }
  1884. func TestQuotaDisabledError(t *testing.T) {
  1885. dataProvider := dataprovider.GetProvider()
  1886. dataprovider.Close(dataProvider)
  1887. config.LoadConfig(configDir, "")
  1888. providerConf := config.GetProviderConf()
  1889. providerConf.TrackQuota = 0
  1890. err := dataprovider.Initialize(providerConf, configDir)
  1891. if err != nil {
  1892. t.Errorf("error initializing data provider")
  1893. }
  1894. httpd.SetDataProvider(dataprovider.GetProvider())
  1895. sftpd.SetDataProvider(dataprovider.GetProvider())
  1896. usePubKey := false
  1897. u := getTestUser(usePubKey)
  1898. u.QuotaFiles = 10
  1899. user, _, err := httpd.AddUser(u, http.StatusOK)
  1900. if err != nil {
  1901. t.Errorf("unable to add user: %v", err)
  1902. }
  1903. client, err := getSftpClient(user, usePubKey)
  1904. if err != nil {
  1905. t.Errorf("unable to create sftp client: %v", err)
  1906. } else {
  1907. defer client.Close()
  1908. testFileName := "test_file.dat"
  1909. testFilePath := filepath.Join(homeBasePath, testFileName)
  1910. testFileSize := int64(65535)
  1911. err = createTestFile(testFilePath, testFileSize)
  1912. if err != nil {
  1913. t.Errorf("unable to create test file: %v", err)
  1914. }
  1915. err = sftpUploadFile(testFilePath, testFileName, testFileSize, client)
  1916. if err != nil {
  1917. t.Errorf("file upload error: %v", err)
  1918. }
  1919. os.Remove(testFilePath)
  1920. }
  1921. _, err = httpd.RemoveUser(user, http.StatusOK)
  1922. if err != nil {
  1923. t.Errorf("unable to remove: %v", err)
  1924. }
  1925. os.RemoveAll(user.GetHomeDir())
  1926. dataProvider = dataprovider.GetProvider()
  1927. dataprovider.Close(dataProvider)
  1928. config.LoadConfig(configDir, "")
  1929. providerConf = config.GetProviderConf()
  1930. err = dataprovider.Initialize(providerConf, configDir)
  1931. if err != nil {
  1932. t.Errorf("error initializing data provider")
  1933. }
  1934. httpd.SetDataProvider(dataprovider.GetProvider())
  1935. sftpd.SetDataProvider(dataprovider.GetProvider())
  1936. }
  1937. func TestMaxSessions(t *testing.T) {
  1938. usePubKey := false
  1939. u := getTestUser(usePubKey)
  1940. u.Username += "1"
  1941. u.MaxSessions = 1
  1942. user, _, err := httpd.AddUser(u, http.StatusOK)
  1943. if err != nil {
  1944. t.Errorf("unable to add user: %v", err)
  1945. }
  1946. client, err := getSftpClient(user, usePubKey)
  1947. if err != nil {
  1948. t.Errorf("unable to create sftp client: %v", err)
  1949. } else {
  1950. defer client.Close()
  1951. _, err := client.Getwd()
  1952. if err != nil {
  1953. t.Errorf("unable to get working dir: %v", err)
  1954. }
  1955. _, err = client.ReadDir(".")
  1956. if err != nil {
  1957. t.Errorf("unable to read remote dir: %v", err)
  1958. }
  1959. _, err = getSftpClient(user, usePubKey)
  1960. if err == nil {
  1961. t.Errorf("max sessions exceeded, new login should not succeed")
  1962. }
  1963. }
  1964. _, err = httpd.RemoveUser(user, http.StatusOK)
  1965. if err != nil {
  1966. t.Errorf("unable to remove user: %v", err)
  1967. }
  1968. os.RemoveAll(user.GetHomeDir())
  1969. }
  1970. func TestQuotaFileReplace(t *testing.T) {
  1971. usePubKey := false
  1972. u := getTestUser(usePubKey)
  1973. u.QuotaFiles = 1000
  1974. user, _, err := httpd.AddUser(u, http.StatusOK)
  1975. if err != nil {
  1976. t.Errorf("unable to add user: %v", err)
  1977. }
  1978. os.RemoveAll(user.GetHomeDir())
  1979. testFileSize := int64(65535)
  1980. testFileName := "test_file.dat"
  1981. testFilePath := filepath.Join(homeBasePath, testFileName)
  1982. client, err := getSftpClient(user, usePubKey)
  1983. if err != nil {
  1984. t.Errorf("unable to create sftp client: %v", err)
  1985. } else {
  1986. defer client.Close()
  1987. expectedQuotaSize := user.UsedQuotaSize + testFileSize
  1988. expectedQuotaFiles := user.UsedQuotaFiles + 1
  1989. err = createTestFile(testFilePath, testFileSize)
  1990. if err != nil {
  1991. t.Errorf("unable to create test file: %v", err)
  1992. }
  1993. err = sftpUploadFile(testFilePath, testFileName, testFileSize, client)
  1994. if err != nil {
  1995. t.Errorf("file upload error: %v", err)
  1996. }
  1997. user, _, err = httpd.GetUserByID(user.ID, http.StatusOK)
  1998. if err != nil {
  1999. t.Errorf("error getting user: %v", err)
  2000. }
  2001. // now replace the same file, the quota must not change
  2002. err = sftpUploadFile(testFilePath, testFileName, testFileSize, client)
  2003. if err != nil {
  2004. t.Errorf("file upload error: %v", err)
  2005. }
  2006. user, _, err = httpd.GetUserByID(user.ID, http.StatusOK)
  2007. if err != nil {
  2008. t.Errorf("error getting user: %v", err)
  2009. }
  2010. if expectedQuotaFiles != user.UsedQuotaFiles {
  2011. t.Errorf("quota files does not match, expected: %v, actual: %v", expectedQuotaFiles, user.UsedQuotaFiles)
  2012. }
  2013. if expectedQuotaSize != user.UsedQuotaSize {
  2014. t.Errorf("quota size does not match, expected: %v, actual: %v", expectedQuotaSize, user.UsedQuotaSize)
  2015. }
  2016. }
  2017. // now set a quota size restriction and upload the same file, upload should fail for space limit exceeded
  2018. user.QuotaSize = testFileSize - 1
  2019. user, _, err = httpd.UpdateUser(user, http.StatusOK)
  2020. if err != nil {
  2021. t.Errorf("error updating user: %v", err)
  2022. }
  2023. client, err = getSftpClient(user, usePubKey)
  2024. if err != nil {
  2025. t.Errorf("unable to create sftp client: %v", err)
  2026. } else {
  2027. err = sftpUploadFile(testFilePath, testFileName, testFileSize, client)
  2028. if err == nil {
  2029. t.Errorf("quota size exceeded, file upload must fail")
  2030. }
  2031. err = client.Remove(testFileName)
  2032. if err != nil {
  2033. t.Errorf("error removing uploaded file: %v", err)
  2034. }
  2035. }
  2036. _, err = httpd.RemoveUser(user, http.StatusOK)
  2037. if err != nil {
  2038. t.Errorf("unable to remove user: %v", err)
  2039. }
  2040. os.Remove(testFilePath)
  2041. os.RemoveAll(user.GetHomeDir())
  2042. }
  2043. func TestQuotaScan(t *testing.T) {
  2044. usePubKey := false
  2045. user, _, err := httpd.AddUser(getTestUser(usePubKey), http.StatusOK)
  2046. if err != nil {
  2047. t.Errorf("unable to add user: %v", err)
  2048. }
  2049. testFileSize := int64(65535)
  2050. expectedQuotaSize := user.UsedQuotaSize + testFileSize
  2051. expectedQuotaFiles := user.UsedQuotaFiles + 1
  2052. client, err := getSftpClient(user, usePubKey)
  2053. if err != nil {
  2054. t.Errorf("unable to create sftp client: %v", err)
  2055. } else {
  2056. defer client.Close()
  2057. testFileName := "test_file.dat"
  2058. testFilePath := filepath.Join(homeBasePath, testFileName)
  2059. err = createTestFile(testFilePath, testFileSize)
  2060. if err != nil {
  2061. t.Errorf("unable to create test file: %v", err)
  2062. }
  2063. err = sftpUploadFile(testFilePath, testFileName, testFileSize, client)
  2064. if err != nil {
  2065. t.Errorf("file upload error: %v", err)
  2066. }
  2067. os.Remove(testFilePath)
  2068. }
  2069. _, err = httpd.RemoveUser(user, http.StatusOK)
  2070. if err != nil {
  2071. t.Errorf("unable to remove user: %v", err)
  2072. }
  2073. // create user with the same home dir, so there is at least an untracked file
  2074. user, _, err = httpd.AddUser(getTestUser(usePubKey), http.StatusOK)
  2075. if err != nil {
  2076. t.Errorf("unable to add user: %v", err)
  2077. }
  2078. _, err = httpd.StartQuotaScan(user, http.StatusCreated)
  2079. if err != nil {
  2080. t.Errorf("error starting quota scan: %v", err)
  2081. }
  2082. err = waitQuotaScans()
  2083. if err != nil {
  2084. t.Errorf("error waiting for active quota scans: %v", err)
  2085. }
  2086. user, _, err = httpd.GetUserByID(user.ID, http.StatusOK)
  2087. if err != nil {
  2088. t.Errorf("error getting user: %v", err)
  2089. }
  2090. if expectedQuotaFiles != user.UsedQuotaFiles {
  2091. t.Errorf("quota files does not match after scan, expected: %v, actual: %v", expectedQuotaFiles, user.UsedQuotaFiles)
  2092. }
  2093. if expectedQuotaSize != user.UsedQuotaSize {
  2094. t.Errorf("quota size does not match after scan, expected: %v, actual: %v", expectedQuotaSize, user.UsedQuotaSize)
  2095. }
  2096. _, err = httpd.RemoveUser(user, http.StatusOK)
  2097. if err != nil {
  2098. t.Errorf("unable to remove user: %v", err)
  2099. }
  2100. os.RemoveAll(user.GetHomeDir())
  2101. }
  2102. func TestMultipleQuotaScans(t *testing.T) {
  2103. if !sftpd.AddQuotaScan(defaultUsername) {
  2104. t.Errorf("add quota failed")
  2105. }
  2106. if sftpd.AddQuotaScan(defaultUsername) {
  2107. t.Errorf("add quota must fail if another scan is already active")
  2108. }
  2109. sftpd.RemoveQuotaScan(defaultUsername)
  2110. activeScans := sftpd.GetQuotaScans()
  2111. if len(activeScans) > 0 {
  2112. t.Errorf("no quota scan must be active: %v", len(activeScans))
  2113. }
  2114. }
  2115. func TestQuotaSize(t *testing.T) {
  2116. usePubKey := false
  2117. testFileSize := int64(65535)
  2118. u := getTestUser(usePubKey)
  2119. u.QuotaFiles = 1
  2120. u.QuotaSize = testFileSize - 1
  2121. user, _, err := httpd.AddUser(u, http.StatusOK)
  2122. if err != nil {
  2123. t.Errorf("unable to add user: %v", err)
  2124. }
  2125. client, err := getSftpClient(user, usePubKey)
  2126. if err != nil {
  2127. t.Errorf("unable to create sftp client: %v", err)
  2128. } else {
  2129. defer client.Close()
  2130. testFileName := "test_file.dat"
  2131. testFilePath := filepath.Join(homeBasePath, testFileName)
  2132. err = createTestFile(testFilePath, testFileSize)
  2133. if err != nil {
  2134. t.Errorf("unable to create test file: %v", err)
  2135. }
  2136. err = sftpUploadFile(testFilePath, testFileName+".quota", testFileSize, client)
  2137. if err != nil {
  2138. t.Errorf("file upload error: %v", err)
  2139. }
  2140. err = sftpUploadFile(testFilePath, testFileName+".quota.1", testFileSize, client)
  2141. if err == nil {
  2142. t.Errorf("user is over quota file upload must fail")
  2143. }
  2144. err = client.Remove(testFileName + ".quota")
  2145. if err != nil {
  2146. t.Errorf("error removing uploaded file: %v", err)
  2147. }
  2148. os.Remove(testFilePath)
  2149. }
  2150. _, err = httpd.RemoveUser(user, http.StatusOK)
  2151. if err != nil {
  2152. t.Errorf("unable to remove user: %v", err)
  2153. }
  2154. os.RemoveAll(user.GetHomeDir())
  2155. }
  2156. func TestBandwidthAndConnections(t *testing.T) {
  2157. usePubKey := false
  2158. testFileSize := int64(131072)
  2159. u := getTestUser(usePubKey)
  2160. u.UploadBandwidth = 30
  2161. u.DownloadBandwidth = 25
  2162. wantedUploadElapsed := 1000 * (testFileSize / 1000) / u.UploadBandwidth
  2163. wantedDownloadElapsed := 1000 * (testFileSize / 1000) / u.DownloadBandwidth
  2164. // 100 ms tolerance
  2165. wantedUploadElapsed -= 100
  2166. wantedDownloadElapsed -= 100
  2167. user, _, err := httpd.AddUser(u, http.StatusOK)
  2168. if err != nil {
  2169. t.Errorf("unable to add user: %v", err)
  2170. }
  2171. client, err := getSftpClient(user, usePubKey)
  2172. if err != nil {
  2173. t.Errorf("unable to create sftp client: %v", err)
  2174. } else {
  2175. defer client.Close()
  2176. testFileName := "test_file.dat"
  2177. testFilePath := filepath.Join(homeBasePath, testFileName)
  2178. err = createTestFile(testFilePath, testFileSize)
  2179. if err != nil {
  2180. t.Errorf("unable to create test file: %v", err)
  2181. }
  2182. startTime := time.Now()
  2183. err = sftpUploadFile(testFilePath, testFileName, testFileSize, client)
  2184. if err != nil {
  2185. t.Errorf("file upload error: %v", err)
  2186. }
  2187. elapsed := time.Since(startTime).Nanoseconds() / 1000000
  2188. if elapsed < (wantedUploadElapsed) {
  2189. t.Errorf("upload bandwidth throttling not respected, elapsed: %v, wanted: %v", elapsed, wantedUploadElapsed)
  2190. }
  2191. startTime = time.Now()
  2192. localDownloadPath := filepath.Join(homeBasePath, "test_download.dat")
  2193. c := sftpDownloadNonBlocking(testFileName, localDownloadPath, testFileSize, client)
  2194. waitForActiveTransfer()
  2195. // wait some additional arbitrary time to wait for transfer activity to happen
  2196. // it is need to reach all the code in CheckIdleConnections
  2197. time.Sleep(100 * time.Millisecond)
  2198. sftpd.CheckIdleConnections()
  2199. err = <-c
  2200. if err != nil {
  2201. t.Errorf("file download error: %v", err)
  2202. }
  2203. elapsed = time.Since(startTime).Nanoseconds() / 1000000
  2204. if elapsed < (wantedDownloadElapsed) {
  2205. t.Errorf("download bandwidth throttling not respected, elapsed: %v, wanted: %v", elapsed, wantedDownloadElapsed)
  2206. }
  2207. // test disconnection
  2208. c = sftpUploadNonBlocking(testFilePath, testFileName+"_partial", testFileSize, client)
  2209. waitForActiveTransfer()
  2210. time.Sleep(100 * time.Millisecond)
  2211. sftpd.CheckIdleConnections()
  2212. stats := sftpd.GetConnectionsStats()
  2213. for _, stat := range stats {
  2214. sftpd.CloseActiveConnection(stat.ConnectionID)
  2215. }
  2216. err = <-c
  2217. if err == nil {
  2218. t.Errorf("connection closed upload must fail")
  2219. }
  2220. os.Remove(testFilePath)
  2221. os.Remove(localDownloadPath)
  2222. }
  2223. _, err = httpd.RemoveUser(user, http.StatusOK)
  2224. if err != nil {
  2225. t.Errorf("unable to remove user: %v", err)
  2226. }
  2227. os.RemoveAll(user.GetHomeDir())
  2228. }
  2229. func TestExtensionsFilters(t *testing.T) {
  2230. usePubKey := true
  2231. u := getTestUser(usePubKey)
  2232. user, _, err := httpd.AddUser(u, http.StatusOK)
  2233. if err != nil {
  2234. t.Errorf("unable to add user: %v", err)
  2235. }
  2236. testFileSize := int64(131072)
  2237. testFileName := "test_file.dat"
  2238. testFilePath := filepath.Join(homeBasePath, testFileName)
  2239. localDownloadPath := filepath.Join(homeBasePath, "test_download.dat")
  2240. client, err := getSftpClient(user, usePubKey)
  2241. if err != nil {
  2242. t.Errorf("unable to create sftp client: %v", err)
  2243. } else {
  2244. defer client.Close()
  2245. err = createTestFile(testFilePath, testFileSize)
  2246. if err != nil {
  2247. t.Errorf("unable to create test file: %v", err)
  2248. }
  2249. err = sftpUploadFile(testFilePath, testFileName, testFileSize, client)
  2250. if err != nil {
  2251. t.Errorf("file upload error: %v", err)
  2252. }
  2253. }
  2254. user.Filters.FileExtensions = []dataprovider.ExtensionsFilter{
  2255. {
  2256. Path: "/",
  2257. AllowedExtensions: []string{".zip"},
  2258. DeniedExtensions: []string{},
  2259. },
  2260. }
  2261. _, _, err = httpd.UpdateUser(user, http.StatusOK)
  2262. if err != nil {
  2263. t.Errorf("unable to update user: %v", err)
  2264. }
  2265. client, err = getSftpClient(user, usePubKey)
  2266. if err != nil {
  2267. t.Errorf("unable to create sftp client: %v", err)
  2268. } else {
  2269. defer client.Close()
  2270. err = sftpUploadFile(testFilePath, testFileName, testFileSize, client)
  2271. if err == nil {
  2272. t.Error("file upload must fail")
  2273. }
  2274. err = sftpDownloadFile(testFileName, localDownloadPath, testFileSize, client)
  2275. if err == nil {
  2276. t.Error("file download must fail")
  2277. }
  2278. err = client.Rename(testFileName, testFileName+"1")
  2279. if err == nil {
  2280. t.Error("rename must fail")
  2281. }
  2282. err = client.Remove(testFileName)
  2283. if err == nil {
  2284. t.Error("remove must fail")
  2285. }
  2286. err = client.Mkdir("dir.zip")
  2287. if err != nil {
  2288. t.Errorf("unexpected error: %v", err)
  2289. }
  2290. err = client.Rename("dir.zip", "dir1.zip")
  2291. if err != nil {
  2292. t.Errorf("unexpected error: %v", err)
  2293. }
  2294. }
  2295. _, err = httpd.RemoveUser(user, http.StatusOK)
  2296. if err != nil {
  2297. t.Errorf("unable to remove user: %v", err)
  2298. }
  2299. os.Remove(testFilePath)
  2300. os.Remove(localDownloadPath)
  2301. os.RemoveAll(user.GetHomeDir())
  2302. }
  2303. func TestVirtualFolders(t *testing.T) {
  2304. usePubKey := true
  2305. u := getTestUser(usePubKey)
  2306. mappedPath := filepath.Join(os.TempDir(), "vdir")
  2307. vdirPath := "/vdir"
  2308. u.VirtualFolders = append(u.VirtualFolders, vfs.VirtualFolder{
  2309. VirtualPath: vdirPath,
  2310. MappedPath: mappedPath,
  2311. })
  2312. os.MkdirAll(mappedPath, 0777)
  2313. user, _, err := httpd.AddUser(u, http.StatusOK)
  2314. if err != nil {
  2315. t.Errorf("unable to add user: %v", err)
  2316. }
  2317. client, err := getSftpClient(user, usePubKey)
  2318. if err != nil {
  2319. t.Errorf("unable to create sftp client: %v", err)
  2320. } else {
  2321. defer client.Close()
  2322. testFileSize := int64(131072)
  2323. testFileName := "test_file.dat"
  2324. testFilePath := filepath.Join(homeBasePath, testFileName)
  2325. err = createTestFile(testFilePath, testFileSize)
  2326. if err != nil {
  2327. t.Errorf("unable to create test file: %v", err)
  2328. }
  2329. localDownloadPath := filepath.Join(homeBasePath, "test_download.dat")
  2330. err = sftpUploadFile(testFilePath, path.Join(vdirPath, testFileName), testFileSize, client)
  2331. if err != nil {
  2332. t.Errorf("file upload error: %v", err)
  2333. }
  2334. err = sftpDownloadFile(path.Join(vdirPath, testFileName), localDownloadPath, testFileSize, client)
  2335. if err != nil {
  2336. t.Errorf("file download error: %v", err)
  2337. }
  2338. err = client.Rename(vdirPath, "new_name")
  2339. if err == nil {
  2340. t.Error("renaming a virtual folder must fail")
  2341. }
  2342. err = client.RemoveDirectory(vdirPath)
  2343. if err == nil {
  2344. t.Error("removing a virtual folder must fail")
  2345. }
  2346. err = client.Mkdir(vdirPath)
  2347. if err == nil {
  2348. t.Error("creating a virtual folder must fail")
  2349. }
  2350. err = client.Symlink(path.Join(vdirPath, testFileName), vdirPath)
  2351. if err == nil {
  2352. t.Error("symlink to a virtual folder must fail")
  2353. }
  2354. os.Remove(testFilePath)
  2355. os.Remove(localDownloadPath)
  2356. }
  2357. _, err = httpd.RemoveUser(user, http.StatusOK)
  2358. if err != nil {
  2359. t.Errorf("unable to remove user: %v", err)
  2360. }
  2361. os.RemoveAll(user.GetHomeDir())
  2362. os.RemoveAll(mappedPath)
  2363. }
  2364. func TestVirtualFoldersQuota(t *testing.T) {
  2365. usePubKey := false
  2366. u := getTestUser(usePubKey)
  2367. u.QuotaFiles = 100
  2368. mappedPath1 := filepath.Join(os.TempDir(), "vdir1")
  2369. vdirPath1 := "/vdir1"
  2370. mappedPath2 := filepath.Join(os.TempDir(), "vdir2")
  2371. vdirPath2 := "/vdir2"
  2372. u.VirtualFolders = append(u.VirtualFolders, vfs.VirtualFolder{
  2373. VirtualPath: vdirPath1,
  2374. MappedPath: mappedPath1,
  2375. })
  2376. u.VirtualFolders = append(u.VirtualFolders, vfs.VirtualFolder{
  2377. VirtualPath: vdirPath2,
  2378. MappedPath: mappedPath2,
  2379. })
  2380. os.MkdirAll(mappedPath1, 0777)
  2381. os.MkdirAll(mappedPath2, 0777)
  2382. user, _, err := httpd.AddUser(u, http.StatusOK)
  2383. if err != nil {
  2384. t.Errorf("unable to add user: %v", err)
  2385. }
  2386. client, err := getSftpClient(user, usePubKey)
  2387. if err != nil {
  2388. t.Errorf("unable to create sftp client: %v", err)
  2389. } else {
  2390. defer client.Close()
  2391. testFileName := "test_file.dat"
  2392. testFileSize := int64(131072)
  2393. testFilePath := filepath.Join(homeBasePath, testFileName)
  2394. err = createTestFile(testFilePath, testFileSize)
  2395. if err != nil {
  2396. t.Errorf("unable to create test file: %v", err)
  2397. }
  2398. err = sftpUploadFile(testFilePath, testFileName, testFileSize, client)
  2399. if err != nil {
  2400. t.Errorf("file upload error: %v", err)
  2401. }
  2402. err = sftpUploadFile(testFilePath, path.Join(vdirPath1, testFileName), testFileSize, client)
  2403. if err != nil {
  2404. t.Errorf("file upload error: %v", err)
  2405. }
  2406. err = sftpUploadFile(testFilePath, path.Join(vdirPath2, testFileName), testFileSize, client)
  2407. if err != nil {
  2408. t.Errorf("file upload error: %v", err)
  2409. }
  2410. expectedQuotaFiles := 3
  2411. expectedQuotaSize := testFileSize * 3
  2412. user, _, err = httpd.GetUserByID(user.ID, http.StatusOK)
  2413. if err != nil {
  2414. t.Errorf("error getting user: %v", err)
  2415. }
  2416. if expectedQuotaFiles != user.UsedQuotaFiles {
  2417. t.Errorf("quota files does not match, expected: %v, actual: %v", expectedQuotaFiles, user.UsedQuotaFiles)
  2418. }
  2419. if expectedQuotaSize != user.UsedQuotaSize {
  2420. t.Errorf("quota size does not match, expected: %v, actual: %v", expectedQuotaSize, user.UsedQuotaSize)
  2421. }
  2422. }
  2423. _, err = httpd.RemoveUser(user, http.StatusOK)
  2424. if err != nil {
  2425. t.Errorf("unable to remove user: %v", err)
  2426. }
  2427. os.RemoveAll(user.GetHomeDir())
  2428. os.RemoveAll(mappedPath1)
  2429. os.RemoveAll(mappedPath2)
  2430. }
  2431. func TestMissingFile(t *testing.T) {
  2432. usePubKey := false
  2433. u := getTestUser(usePubKey)
  2434. user, _, err := httpd.AddUser(u, http.StatusOK)
  2435. if err != nil {
  2436. t.Errorf("unable to add user: %v", err)
  2437. }
  2438. client, err := getSftpClient(user, usePubKey)
  2439. if err != nil {
  2440. t.Errorf("unable to create sftp client: %v", err)
  2441. } else {
  2442. defer client.Close()
  2443. localDownloadPath := filepath.Join(homeBasePath, "test_download.dat")
  2444. err = sftpDownloadFile("missing_file", localDownloadPath, 0, client)
  2445. if err == nil {
  2446. t.Errorf("download missing file must fail")
  2447. }
  2448. os.Remove(localDownloadPath)
  2449. }
  2450. _, err = httpd.RemoveUser(user, http.StatusOK)
  2451. if err != nil {
  2452. t.Errorf("unable to remove user: %v", err)
  2453. }
  2454. os.RemoveAll(user.GetHomeDir())
  2455. }
  2456. func TestOpenError(t *testing.T) {
  2457. if runtime.GOOS == "windows" {
  2458. t.Skip("this test is not available on Windows")
  2459. }
  2460. usePubKey := false
  2461. u := getTestUser(usePubKey)
  2462. user, _, err := httpd.AddUser(u, http.StatusOK)
  2463. if err != nil {
  2464. t.Errorf("unable to add user: %v", err)
  2465. }
  2466. os.RemoveAll(user.GetHomeDir())
  2467. client, err := getSftpClient(user, usePubKey)
  2468. if err != nil {
  2469. t.Errorf("unable to create sftp client: %v", err)
  2470. } else {
  2471. defer client.Close()
  2472. os.Chmod(user.GetHomeDir(), 0001)
  2473. _, err = client.ReadDir(".")
  2474. if err == nil {
  2475. t.Errorf("read dir must fail if we have no filesystem read permissions")
  2476. }
  2477. os.Chmod(user.GetHomeDir(), 0755)
  2478. testFileSize := int64(65535)
  2479. testFileName := "test_file.dat"
  2480. testFilePath := filepath.Join(user.GetHomeDir(), testFileName)
  2481. err = createTestFile(testFilePath, testFileSize)
  2482. if err != nil {
  2483. t.Errorf("unable to create test file: %v", err)
  2484. }
  2485. _, err = client.Stat(testFileName)
  2486. if err != nil {
  2487. t.Errorf("file stat error: %v", err)
  2488. }
  2489. localDownloadPath := filepath.Join(homeBasePath, "test_download.dat")
  2490. err = sftpDownloadFile(testFileName, localDownloadPath, testFileSize, client)
  2491. if err != nil {
  2492. t.Errorf("file download error: %v", err)
  2493. }
  2494. os.Chmod(testFilePath, 0001)
  2495. err = sftpDownloadFile(testFileName, localDownloadPath, testFileSize, client)
  2496. if err == nil {
  2497. t.Errorf("file download must fail if we have no filesystem read permissions")
  2498. }
  2499. err = sftpUploadFile(localDownloadPath, testFileName, testFileSize, client)
  2500. if err == nil {
  2501. t.Errorf("upload must fail if we have no filesystem write permissions")
  2502. }
  2503. err = client.Mkdir("test")
  2504. if err != nil {
  2505. t.Errorf("error making dir: %v", err)
  2506. }
  2507. os.Chmod(user.GetHomeDir(), 0000)
  2508. _, err = client.Lstat(testFileName)
  2509. if err == nil {
  2510. t.Errorf("file stat must fail if we have no filesystem read permissions")
  2511. }
  2512. os.Chmod(user.GetHomeDir(), 0755)
  2513. os.Chmod(filepath.Join(user.GetHomeDir(), "test"), 0000)
  2514. err = client.Rename(testFileName, path.Join("test", testFileName))
  2515. if err == nil || !strings.Contains(err.Error(), sftp.ErrSSHFxPermissionDenied.Error()) {
  2516. t.Errorf("unexpected error: %v expected: %v", err, sftp.ErrSSHFxPermissionDenied)
  2517. }
  2518. os.Chmod(filepath.Join(user.GetHomeDir(), "test"), 0755)
  2519. os.Remove(testFilePath)
  2520. os.Remove(localDownloadPath)
  2521. }
  2522. _, err = httpd.RemoveUser(user, http.StatusOK)
  2523. if err != nil {
  2524. t.Errorf("unable to remove user: %v", err)
  2525. }
  2526. os.RemoveAll(user.GetHomeDir())
  2527. }
  2528. func TestOverwriteDirWithFile(t *testing.T) {
  2529. usePubKey := false
  2530. u := getTestUser(usePubKey)
  2531. user, _, err := httpd.AddUser(u, http.StatusOK)
  2532. if err != nil {
  2533. t.Errorf("unable to add user: %v", err)
  2534. }
  2535. client, err := getSftpClient(user, usePubKey)
  2536. if err != nil {
  2537. t.Errorf("unable to create sftp client: %v", err)
  2538. } else {
  2539. defer client.Close()
  2540. testFileSize := int64(65535)
  2541. testFileName := "test_file.dat"
  2542. testDirName := "test_dir"
  2543. testFilePath := filepath.Join(homeBasePath, testFileName)
  2544. err = createTestFile(testFilePath, testFileSize)
  2545. if err != nil {
  2546. t.Errorf("unable to create test file: %v", err)
  2547. }
  2548. err = client.Mkdir(testDirName)
  2549. if err != nil {
  2550. t.Errorf("mkdir error: %v", err)
  2551. }
  2552. err = sftpUploadFile(testFilePath, testDirName, testFileSize, client)
  2553. if err == nil {
  2554. t.Errorf("copying a file over an existing dir must fail")
  2555. }
  2556. err = sftpUploadFile(testFilePath, testFileName, testFileSize, client)
  2557. if err != nil {
  2558. t.Errorf("file upload error: %v", err)
  2559. }
  2560. err = client.Rename(testFileName, testDirName)
  2561. if err == nil {
  2562. t.Errorf("rename a file over an existing dir must fail")
  2563. }
  2564. err = client.RemoveDirectory(testDirName)
  2565. if err != nil {
  2566. t.Errorf("dir remove error: %v", err)
  2567. }
  2568. err = client.Remove(testFileName)
  2569. if err != nil {
  2570. t.Errorf("error removing uploaded file: %v", err)
  2571. }
  2572. os.Remove(testFilePath)
  2573. }
  2574. _, err = httpd.RemoveUser(user, http.StatusOK)
  2575. if err != nil {
  2576. t.Errorf("unable to remove user: %v", err)
  2577. }
  2578. os.RemoveAll(user.GetHomeDir())
  2579. }
  2580. func TestPasswordsHashPbkdf2Sha1(t *testing.T) {
  2581. pbkdf2Pwd := "$pbkdf2-sha1$150000$DveVjgYUD05R$X6ydQZdyMeOvpgND2nqGR/0GGic="
  2582. pbkdf2ClearPwd := "password"
  2583. usePubKey := false
  2584. u := getTestUser(usePubKey)
  2585. u.Password = pbkdf2Pwd
  2586. user, _, err := httpd.AddUser(u, http.StatusOK)
  2587. if err != nil {
  2588. t.Errorf("unable to add user: %v", err)
  2589. }
  2590. user.Password = pbkdf2ClearPwd
  2591. client, err := getSftpClient(user, usePubKey)
  2592. if err != nil {
  2593. t.Errorf("unable to login with pkkdf2 sha1 password: %v", err)
  2594. } else {
  2595. defer client.Close()
  2596. _, err = client.Getwd()
  2597. if err != nil {
  2598. t.Errorf("unable to get working dir with pkkdf2 sha1 password: %v", err)
  2599. }
  2600. }
  2601. user.Password = pbkdf2Pwd
  2602. _, err = getSftpClient(user, usePubKey)
  2603. if err == nil {
  2604. t.Errorf("login with wrong password must fail")
  2605. }
  2606. _, err = httpd.RemoveUser(user, http.StatusOK)
  2607. if err != nil {
  2608. t.Errorf("unable to remove user: %v", err)
  2609. }
  2610. os.RemoveAll(user.GetHomeDir())
  2611. }
  2612. func TestPasswordsHashPbkdf2Sha256(t *testing.T) {
  2613. pbkdf2Pwd := "$pbkdf2-sha256$150000$E86a9YMX3zC7$R5J62hsSq+pYw00hLLPKBbcGXmq7fj5+/M0IFoYtZbo="
  2614. pbkdf2ClearPwd := "password"
  2615. usePubKey := false
  2616. u := getTestUser(usePubKey)
  2617. u.Password = pbkdf2Pwd
  2618. user, _, err := httpd.AddUser(u, http.StatusOK)
  2619. if err != nil {
  2620. t.Errorf("unable to add user: %v", err)
  2621. }
  2622. user.Password = pbkdf2ClearPwd
  2623. client, err := getSftpClient(user, usePubKey)
  2624. if err != nil {
  2625. t.Errorf("unable to login with pkkdf2 sha256 password: %v", err)
  2626. } else {
  2627. defer client.Close()
  2628. _, err = client.Getwd()
  2629. if err != nil {
  2630. t.Errorf("unable to get working dir with pkkdf2 sha256 password: %v", err)
  2631. }
  2632. }
  2633. user.Password = pbkdf2Pwd
  2634. _, err = getSftpClient(user, usePubKey)
  2635. if err == nil {
  2636. t.Errorf("login with wrong password must fail")
  2637. }
  2638. _, err = httpd.RemoveUser(user, http.StatusOK)
  2639. if err != nil {
  2640. t.Errorf("unable to remove user: %v", err)
  2641. }
  2642. os.RemoveAll(user.GetHomeDir())
  2643. }
  2644. func TestPasswordsHashPbkdf2Sha512(t *testing.T) {
  2645. pbkdf2Pwd := "$pbkdf2-sha512$150000$dsu7T5R3IaVQ$1hFXPO1ntRBcoWkSLKw+s4sAP09Xtu4Ya7CyxFq64jM9zdUg8eRJVr3NcR2vQgb0W9HHvZaILHsL4Q/Vr6arCg=="
  2646. pbkdf2ClearPwd := "password"
  2647. usePubKey := false
  2648. u := getTestUser(usePubKey)
  2649. u.Password = pbkdf2Pwd
  2650. user, _, err := httpd.AddUser(u, http.StatusOK)
  2651. if err != nil {
  2652. t.Errorf("unable to add user: %v", err)
  2653. }
  2654. user.Password = pbkdf2ClearPwd
  2655. client, err := getSftpClient(user, usePubKey)
  2656. if err != nil {
  2657. t.Errorf("unable to login with pkkdf2 sha512 password: %v", err)
  2658. } else {
  2659. defer client.Close()
  2660. _, err = client.Getwd()
  2661. if err != nil {
  2662. t.Errorf("unable to get working dir with pkkdf2 sha512 password: %v", err)
  2663. }
  2664. }
  2665. user.Password = pbkdf2Pwd
  2666. _, err = getSftpClient(user, usePubKey)
  2667. if err == nil {
  2668. t.Errorf("login with wrong password must fail")
  2669. }
  2670. _, err = httpd.RemoveUser(user, http.StatusOK)
  2671. if err != nil {
  2672. t.Errorf("unable to remove user: %v", err)
  2673. }
  2674. os.RemoveAll(user.GetHomeDir())
  2675. }
  2676. func TestPasswordsHashPbkdf2Sha256_389DS(t *testing.T) {
  2677. pbkdf389dsPwd := "{PBKDF2_SHA256}AAAIAMZIKG4ie44zJY4HOXI+upFR74PzWLUQV63jg+zzkbEjCK3N4qW583WF7EdcpeoOMQ4HY3aWEXB6lnXhXJixbJkU4vVSJkL6YCbU3TrD0qn1uUUVSkaIgAOtmZENitwbhYhiWfEzGyAtFqkFd75P5xhWJEog9XhQKYrR0f7S3WGGZq03JRcLJ460xpU97bE/sWRn7sshgkWzLuyrs0I+XRKmK7FJeaA9zd+1m44Y3IVmZ2YLdKATzjRHAIgpBC6i1TWOcpKJT1+feP1C9hrxH8vU9baw9thNiO8jSHaZlwb//KpJFe0ahVnG/1ubiG8cO0+CCqDqXVJR6Vr4QZxHP+4pwooW+4TP/L+HFdyA1y6z4gKfqYnBsmb3sD1R1TbxfH4btTdvgZAnBk9CmR3QASkFXxeTYsrmNd5+9IAHc6dm"
  2678. pbkdf389dsPwd = pbkdf389dsPwd[15:]
  2679. hashBytes, err := base64.StdEncoding.DecodeString(pbkdf389dsPwd)
  2680. if err != nil {
  2681. t.Errorf("unable to decode 389ds password: %v", err)
  2682. }
  2683. iterBytes := hashBytes[0:4]
  2684. var iterations int32
  2685. binary.Read(bytes.NewBuffer(iterBytes), binary.BigEndian, &iterations)
  2686. salt := hashBytes[4:68]
  2687. targetKey := hashBytes[68:]
  2688. key := base64.StdEncoding.EncodeToString(targetKey)
  2689. pbkdf2Pwd := fmt.Sprintf("$pbkdf2-b64salt-sha256$%v$%v$%v", iterations, base64.StdEncoding.EncodeToString(salt), key)
  2690. pbkdf2ClearPwd := "password"
  2691. usePubKey := false
  2692. u := getTestUser(usePubKey)
  2693. u.Password = pbkdf2Pwd
  2694. user, _, err := httpd.AddUser(u, http.StatusOK)
  2695. if err != nil {
  2696. t.Errorf("unable to add user: %v", err)
  2697. }
  2698. user.Password = pbkdf2ClearPwd
  2699. client, err := getSftpClient(user, usePubKey)
  2700. if err != nil {
  2701. t.Errorf("unable to login with pkkdf2 sha256 password: %v", err)
  2702. } else {
  2703. defer client.Close()
  2704. _, err = client.Getwd()
  2705. if err != nil {
  2706. t.Errorf("unable to get working dir with pkkdf2 sha256 password: %v", err)
  2707. }
  2708. }
  2709. user.Password = pbkdf2Pwd
  2710. _, err = getSftpClient(user, usePubKey)
  2711. if err == nil {
  2712. t.Errorf("login with wrong password must fail")
  2713. }
  2714. _, err = httpd.RemoveUser(user, http.StatusOK)
  2715. if err != nil {
  2716. t.Errorf("unable to remove user: %v", err)
  2717. }
  2718. os.RemoveAll(user.GetHomeDir())
  2719. }
  2720. func TestPasswordsHashBcrypt(t *testing.T) {
  2721. bcryptPwd := "$2a$14$ajq8Q7fbtFRQvXpdCq7Jcuy.Rx1h/L4J60Otx.gyNLbAYctGMJ9tK"
  2722. bcryptClearPwd := "secret"
  2723. usePubKey := false
  2724. u := getTestUser(usePubKey)
  2725. u.Password = bcryptPwd
  2726. user, _, err := httpd.AddUser(u, http.StatusOK)
  2727. if err != nil {
  2728. t.Errorf("unable to add user: %v", err)
  2729. }
  2730. user.Password = bcryptClearPwd
  2731. client, err := getSftpClient(user, usePubKey)
  2732. if err != nil {
  2733. t.Errorf("unable to login with bcrypt password: %v", err)
  2734. } else {
  2735. defer client.Close()
  2736. _, err = client.Getwd()
  2737. if err != nil {
  2738. t.Errorf("unable to get working dir with bcrypt password: %v", err)
  2739. }
  2740. }
  2741. user.Password = bcryptPwd
  2742. _, err = getSftpClient(user, usePubKey)
  2743. if err == nil {
  2744. t.Errorf("login with wrong password must fail")
  2745. }
  2746. _, err = httpd.RemoveUser(user, http.StatusOK)
  2747. if err != nil {
  2748. t.Errorf("unable to remove user: %v", err)
  2749. }
  2750. os.RemoveAll(user.GetHomeDir())
  2751. }
  2752. func TestPasswordsHashSHA512Crypt(t *testing.T) {
  2753. sha512CryptPwd := "$6$459ead56b72e44bc$uog86fUxscjt28BZxqFBE2pp2QD8P/1e98MNF75Z9xJfQvOckZnQ/1YJqiq1XeytPuDieHZvDAMoP7352ELkO1"
  2754. clearPwd := "secret"
  2755. usePubKey := false
  2756. u := getTestUser(usePubKey)
  2757. u.Password = sha512CryptPwd
  2758. user, _, err := httpd.AddUser(u, http.StatusOK)
  2759. if err != nil {
  2760. t.Errorf("unable to add user: %v", err)
  2761. }
  2762. user.Password = clearPwd
  2763. client, err := getSftpClient(user, usePubKey)
  2764. if err != nil {
  2765. t.Errorf("unable to login with sha512 crypt password: %v", err)
  2766. } else {
  2767. defer client.Close()
  2768. _, err = client.Getwd()
  2769. if err != nil {
  2770. t.Errorf("unable to get working dir with sha512 crypt password: %v", err)
  2771. }
  2772. }
  2773. user.Password = sha512CryptPwd
  2774. _, err = getSftpClient(user, usePubKey)
  2775. if err == nil {
  2776. t.Errorf("login with wrong password must fail")
  2777. }
  2778. _, err = httpd.RemoveUser(user, http.StatusOK)
  2779. if err != nil {
  2780. t.Errorf("unable to remove user: %v", err)
  2781. }
  2782. os.RemoveAll(user.GetHomeDir())
  2783. }
  2784. func TestPasswordsHashMD5Crypt(t *testing.T) {
  2785. md5CryptPwd := "$1$b5caebda$VODr/nyhGWgZaY8sJ4x05."
  2786. clearPwd := "password"
  2787. usePubKey := false
  2788. u := getTestUser(usePubKey)
  2789. u.Password = md5CryptPwd
  2790. user, _, err := httpd.AddUser(u, http.StatusOK)
  2791. if err != nil {
  2792. t.Errorf("unable to add user: %v", err)
  2793. }
  2794. user.Password = clearPwd
  2795. client, err := getSftpClient(user, usePubKey)
  2796. if err != nil {
  2797. t.Errorf("unable to login with md5 crypt password: %v", err)
  2798. } else {
  2799. defer client.Close()
  2800. _, err = client.Getwd()
  2801. if err != nil {
  2802. t.Errorf("unable to get working dir with md5 crypt password: %v", err)
  2803. }
  2804. }
  2805. user.Password = md5CryptPwd
  2806. _, err = getSftpClient(user, usePubKey)
  2807. if err == nil {
  2808. t.Errorf("login with wrong password must fail")
  2809. }
  2810. _, err = httpd.RemoveUser(user, http.StatusOK)
  2811. if err != nil {
  2812. t.Errorf("unable to remove user: %v", err)
  2813. }
  2814. os.RemoveAll(user.GetHomeDir())
  2815. }
  2816. func TestPasswordsHashMD5CryptApr1(t *testing.T) {
  2817. md5CryptPwd := "$apr1$OBWLeSme$WoJbB736e7kKxMBIAqilb1"
  2818. clearPwd := "password"
  2819. usePubKey := false
  2820. u := getTestUser(usePubKey)
  2821. u.Password = md5CryptPwd
  2822. user, _, err := httpd.AddUser(u, http.StatusOK)
  2823. if err != nil {
  2824. t.Errorf("unable to add user: %v", err)
  2825. }
  2826. user.Password = clearPwd
  2827. client, err := getSftpClient(user, usePubKey)
  2828. if err != nil {
  2829. t.Errorf("unable to login with md5 crypt password: %v", err)
  2830. } else {
  2831. defer client.Close()
  2832. _, err = client.Getwd()
  2833. if err != nil {
  2834. t.Errorf("unable to get working dir with md5 crypt password: %v", err)
  2835. }
  2836. }
  2837. user.Password = md5CryptPwd
  2838. _, err = getSftpClient(user, usePubKey)
  2839. if err == nil {
  2840. t.Errorf("login with wrong password must fail")
  2841. }
  2842. _, err = httpd.RemoveUser(user, http.StatusOK)
  2843. if err != nil {
  2844. t.Errorf("unable to remove user: %v", err)
  2845. }
  2846. os.RemoveAll(user.GetHomeDir())
  2847. }
  2848. func TestPermList(t *testing.T) {
  2849. usePubKey := true
  2850. u := getTestUser(usePubKey)
  2851. u.Permissions["/"] = []string{dataprovider.PermDownload, dataprovider.PermUpload, dataprovider.PermDelete, dataprovider.PermRename,
  2852. dataprovider.PermCreateDirs, dataprovider.PermCreateSymlinks, dataprovider.PermOverwrite, dataprovider.PermChmod,
  2853. dataprovider.PermChown, dataprovider.PermChtimes}
  2854. user, _, err := httpd.AddUser(u, http.StatusOK)
  2855. if err != nil {
  2856. t.Errorf("unable to add user: %v", err)
  2857. }
  2858. client, err := getSftpClient(user, usePubKey)
  2859. if err != nil {
  2860. t.Errorf("unable to create sftp client: %v", err)
  2861. } else {
  2862. defer client.Close()
  2863. _, err = client.ReadDir(".")
  2864. if err == nil {
  2865. t.Errorf("read remote dir without permission should not succeed")
  2866. }
  2867. _, err = client.Stat("test_file")
  2868. if err == nil {
  2869. t.Errorf("stat remote file without permission should not succeed")
  2870. }
  2871. }
  2872. _, err = httpd.RemoveUser(user, http.StatusOK)
  2873. if err != nil {
  2874. t.Errorf("unable to remove user: %v", err)
  2875. }
  2876. os.RemoveAll(user.GetHomeDir())
  2877. }
  2878. func TestPermDownload(t *testing.T) {
  2879. usePubKey := true
  2880. u := getTestUser(usePubKey)
  2881. u.Permissions["/"] = []string{dataprovider.PermListItems, dataprovider.PermUpload, dataprovider.PermDelete, dataprovider.PermRename,
  2882. dataprovider.PermCreateDirs, dataprovider.PermCreateSymlinks, dataprovider.PermOverwrite, dataprovider.PermChmod,
  2883. dataprovider.PermChown, dataprovider.PermChtimes}
  2884. user, _, err := httpd.AddUser(u, http.StatusOK)
  2885. if err != nil {
  2886. t.Errorf("unable to add user: %v", err)
  2887. }
  2888. client, err := getSftpClient(user, usePubKey)
  2889. if err != nil {
  2890. t.Errorf("unable to create sftp client: %v", err)
  2891. } else {
  2892. defer client.Close()
  2893. testFileName := "test_file.dat"
  2894. testFilePath := filepath.Join(homeBasePath, testFileName)
  2895. testFileSize := int64(65535)
  2896. err = createTestFile(testFilePath, testFileSize)
  2897. if err != nil {
  2898. t.Errorf("unable to create test file: %v", err)
  2899. }
  2900. err = sftpUploadFile(testFilePath, testFileName, testFileSize, client)
  2901. if err != nil {
  2902. t.Errorf("file upload error: %v", err)
  2903. }
  2904. localDownloadPath := filepath.Join(homeBasePath, "test_download.dat")
  2905. err = sftpDownloadFile(testFileName, localDownloadPath, testFileSize, client)
  2906. if err == nil {
  2907. t.Errorf("file download without permission should not succeed")
  2908. }
  2909. err = client.Remove(testFileName)
  2910. if err != nil {
  2911. t.Errorf("error removing uploaded file: %v", err)
  2912. }
  2913. os.Remove(testFilePath)
  2914. os.Remove(localDownloadPath)
  2915. }
  2916. _, err = httpd.RemoveUser(user, http.StatusOK)
  2917. if err != nil {
  2918. t.Errorf("unable to remove user: %v", err)
  2919. }
  2920. os.RemoveAll(user.GetHomeDir())
  2921. }
  2922. func TestPermUpload(t *testing.T) {
  2923. usePubKey := false
  2924. u := getTestUser(usePubKey)
  2925. u.Permissions["/"] = []string{dataprovider.PermListItems, dataprovider.PermDownload, dataprovider.PermDelete, dataprovider.PermRename,
  2926. dataprovider.PermCreateDirs, dataprovider.PermCreateSymlinks, dataprovider.PermOverwrite, dataprovider.PermChmod,
  2927. dataprovider.PermChown, dataprovider.PermChtimes}
  2928. user, _, err := httpd.AddUser(u, http.StatusOK)
  2929. if err != nil {
  2930. t.Errorf("unable to add user: %v", err)
  2931. }
  2932. client, err := getSftpClient(user, usePubKey)
  2933. if err != nil {
  2934. t.Errorf("unable to create sftp client: %v", err)
  2935. } else {
  2936. defer client.Close()
  2937. testFileName := "test_file.dat"
  2938. testFilePath := filepath.Join(homeBasePath, testFileName)
  2939. testFileSize := int64(65535)
  2940. err = createTestFile(testFilePath, testFileSize)
  2941. if err != nil {
  2942. t.Errorf("unable to create test file: %v", err)
  2943. }
  2944. err = sftpUploadFile(testFilePath, testFileName, testFileSize, client)
  2945. if err == nil {
  2946. t.Errorf("file upload without permission should not succeed")
  2947. }
  2948. os.Remove(testFilePath)
  2949. }
  2950. _, err = httpd.RemoveUser(user, http.StatusOK)
  2951. if err != nil {
  2952. t.Errorf("unable to remove user: %v", err)
  2953. }
  2954. os.RemoveAll(user.GetHomeDir())
  2955. }
  2956. func TestPermOverwrite(t *testing.T) {
  2957. usePubKey := false
  2958. u := getTestUser(usePubKey)
  2959. u.Permissions["/"] = []string{dataprovider.PermListItems, dataprovider.PermDownload, dataprovider.PermUpload, dataprovider.PermDelete,
  2960. dataprovider.PermRename, dataprovider.PermCreateDirs, dataprovider.PermCreateSymlinks, dataprovider.PermChmod,
  2961. dataprovider.PermChown, dataprovider.PermChtimes}
  2962. user, _, err := httpd.AddUser(u, http.StatusOK)
  2963. if err != nil {
  2964. t.Errorf("unable to add user: %v", err)
  2965. }
  2966. client, err := getSftpClient(user, usePubKey)
  2967. if err != nil {
  2968. t.Errorf("unable to create sftp client: %v", err)
  2969. } else {
  2970. defer client.Close()
  2971. testFileName := "test_file.dat"
  2972. testFilePath := filepath.Join(homeBasePath, testFileName)
  2973. testFileSize := int64(65535)
  2974. err = createTestFile(testFilePath, testFileSize)
  2975. if err != nil {
  2976. t.Errorf("unable to create test file: %v", err)
  2977. }
  2978. err = sftpUploadFile(testFilePath, testFileName, testFileSize, client)
  2979. if err != nil {
  2980. t.Errorf("error uploading file: %v", err)
  2981. }
  2982. err = sftpUploadFile(testFilePath, testFileName, testFileSize, client)
  2983. if err == nil {
  2984. t.Errorf("file overwrite without permission should not succeed")
  2985. }
  2986. os.Remove(testFilePath)
  2987. }
  2988. _, err = httpd.RemoveUser(user, http.StatusOK)
  2989. if err != nil {
  2990. t.Errorf("unable to remove user: %v", err)
  2991. }
  2992. os.RemoveAll(user.GetHomeDir())
  2993. }
  2994. func TestPermDelete(t *testing.T) {
  2995. usePubKey := false
  2996. u := getTestUser(usePubKey)
  2997. u.Permissions["/"] = []string{dataprovider.PermListItems, dataprovider.PermDownload, dataprovider.PermUpload, dataprovider.PermRename,
  2998. dataprovider.PermCreateDirs, dataprovider.PermCreateSymlinks, dataprovider.PermOverwrite, dataprovider.PermChmod,
  2999. dataprovider.PermChown, dataprovider.PermChtimes}
  3000. user, _, err := httpd.AddUser(u, http.StatusOK)
  3001. if err != nil {
  3002. t.Errorf("unable to add user: %v", err)
  3003. }
  3004. client, err := getSftpClient(user, usePubKey)
  3005. if err != nil {
  3006. t.Errorf("unable to create sftp client: %v", err)
  3007. } else {
  3008. defer client.Close()
  3009. testFileName := "test_file.dat"
  3010. testFilePath := filepath.Join(homeBasePath, testFileName)
  3011. testFileSize := int64(65535)
  3012. err = createTestFile(testFilePath, testFileSize)
  3013. if err != nil {
  3014. t.Errorf("unable to create test file: %v", err)
  3015. }
  3016. err = sftpUploadFile(testFilePath, testFileName, testFileSize, client)
  3017. if err != nil {
  3018. t.Errorf("file upload error: %v", err)
  3019. }
  3020. err = client.Remove(testFileName)
  3021. if err == nil {
  3022. t.Errorf("delete without permission should not succeed")
  3023. }
  3024. os.Remove(testFilePath)
  3025. }
  3026. _, err = httpd.RemoveUser(user, http.StatusOK)
  3027. if err != nil {
  3028. t.Errorf("unable to remove user: %v", err)
  3029. }
  3030. os.RemoveAll(user.GetHomeDir())
  3031. }
  3032. func TestPermRename(t *testing.T) {
  3033. usePubKey := false
  3034. u := getTestUser(usePubKey)
  3035. u.Permissions["/"] = []string{dataprovider.PermListItems, dataprovider.PermDownload, dataprovider.PermUpload, dataprovider.PermDelete,
  3036. dataprovider.PermCreateDirs, dataprovider.PermCreateSymlinks, dataprovider.PermOverwrite, dataprovider.PermChmod,
  3037. dataprovider.PermChown, dataprovider.PermChtimes}
  3038. user, _, err := httpd.AddUser(u, http.StatusOK)
  3039. if err != nil {
  3040. t.Errorf("unable to add user: %v", err)
  3041. }
  3042. client, err := getSftpClient(user, usePubKey)
  3043. if err != nil {
  3044. t.Errorf("unable to create sftp client: %v", err)
  3045. } else {
  3046. defer client.Close()
  3047. testFileName := "test_file.dat"
  3048. testFilePath := filepath.Join(homeBasePath, testFileName)
  3049. testFileSize := int64(65535)
  3050. err = createTestFile(testFilePath, testFileSize)
  3051. if err != nil {
  3052. t.Errorf("unable to create test file: %v", err)
  3053. }
  3054. err = sftpUploadFile(testFilePath, testFileName, testFileSize, client)
  3055. if err != nil {
  3056. t.Errorf("file upload error: %v", err)
  3057. }
  3058. err = client.Rename(testFileName, testFileName+".rename")
  3059. if err == nil {
  3060. t.Errorf("rename without permission should not succeed")
  3061. }
  3062. err = client.Remove(testFileName)
  3063. if err != nil {
  3064. t.Errorf("error removing uploaded file: %v", err)
  3065. }
  3066. os.Remove(testFilePath)
  3067. }
  3068. _, err = httpd.RemoveUser(user, http.StatusOK)
  3069. if err != nil {
  3070. t.Errorf("unable to remove user: %v", err)
  3071. }
  3072. os.RemoveAll(user.GetHomeDir())
  3073. }
  3074. func TestPermCreateDirs(t *testing.T) {
  3075. usePubKey := false
  3076. u := getTestUser(usePubKey)
  3077. u.Permissions["/"] = []string{dataprovider.PermListItems, dataprovider.PermDownload, dataprovider.PermUpload, dataprovider.PermDelete,
  3078. dataprovider.PermRename, dataprovider.PermCreateSymlinks, dataprovider.PermOverwrite, dataprovider.PermChmod,
  3079. dataprovider.PermChown, dataprovider.PermChtimes}
  3080. user, _, err := httpd.AddUser(u, http.StatusOK)
  3081. if err != nil {
  3082. t.Errorf("unable to add user: %v", err)
  3083. }
  3084. client, err := getSftpClient(user, usePubKey)
  3085. if err != nil {
  3086. t.Errorf("unable to create sftp client: %v", err)
  3087. } else {
  3088. defer client.Close()
  3089. err = client.Mkdir("testdir")
  3090. if err == nil {
  3091. t.Errorf("mkdir without permission should not succeed")
  3092. }
  3093. }
  3094. _, err = httpd.RemoveUser(user, http.StatusOK)
  3095. if err != nil {
  3096. t.Errorf("unable to remove user: %v", err)
  3097. }
  3098. os.RemoveAll(user.GetHomeDir())
  3099. }
  3100. func TestPermSymlink(t *testing.T) {
  3101. usePubKey := false
  3102. u := getTestUser(usePubKey)
  3103. u.Permissions["/"] = []string{dataprovider.PermListItems, dataprovider.PermDownload, dataprovider.PermUpload, dataprovider.PermDelete,
  3104. dataprovider.PermRename, dataprovider.PermCreateDirs, dataprovider.PermOverwrite, dataprovider.PermChmod, dataprovider.PermChown,
  3105. dataprovider.PermChtimes}
  3106. user, _, err := httpd.AddUser(u, http.StatusOK)
  3107. if err != nil {
  3108. t.Errorf("unable to add user: %v", err)
  3109. }
  3110. client, err := getSftpClient(user, usePubKey)
  3111. if err != nil {
  3112. t.Errorf("unable to create sftp client: %v", err)
  3113. } else {
  3114. defer client.Close()
  3115. testFileName := "test_file.dat"
  3116. testFilePath := filepath.Join(homeBasePath, testFileName)
  3117. testFileSize := int64(65535)
  3118. err = createTestFile(testFilePath, testFileSize)
  3119. if err != nil {
  3120. t.Errorf("unable to create test file: %v", err)
  3121. }
  3122. err = sftpUploadFile(testFilePath, testFileName, testFileSize, client)
  3123. if err != nil {
  3124. t.Errorf("file upload error: %v", err)
  3125. }
  3126. err = client.Symlink(testFilePath, testFilePath+".symlink")
  3127. if err == nil {
  3128. t.Errorf("symlink without permission should not succeed")
  3129. }
  3130. err = client.Remove(testFileName)
  3131. if err != nil {
  3132. t.Errorf("error removing uploaded file: %v", err)
  3133. }
  3134. os.Remove(testFilePath)
  3135. }
  3136. _, err = httpd.RemoveUser(user, http.StatusOK)
  3137. if err != nil {
  3138. t.Errorf("unable to remove user: %v", err)
  3139. }
  3140. os.RemoveAll(user.GetHomeDir())
  3141. }
  3142. func TestPermChmod(t *testing.T) {
  3143. usePubKey := false
  3144. u := getTestUser(usePubKey)
  3145. u.Permissions["/"] = []string{dataprovider.PermListItems, dataprovider.PermDownload, dataprovider.PermUpload, dataprovider.PermDelete,
  3146. dataprovider.PermRename, dataprovider.PermCreateDirs, dataprovider.PermCreateSymlinks, dataprovider.PermOverwrite,
  3147. dataprovider.PermChown, dataprovider.PermChtimes}
  3148. user, _, err := httpd.AddUser(u, http.StatusOK)
  3149. if err != nil {
  3150. t.Errorf("unable to add user: %v", err)
  3151. }
  3152. client, err := getSftpClient(user, usePubKey)
  3153. if err != nil {
  3154. t.Errorf("unable to create sftp client: %v", err)
  3155. } else {
  3156. defer client.Close()
  3157. testFileName := "test_file.dat"
  3158. testFilePath := filepath.Join(homeBasePath, testFileName)
  3159. testFileSize := int64(65535)
  3160. err = createTestFile(testFilePath, testFileSize)
  3161. if err != nil {
  3162. t.Errorf("unable to create test file: %v", err)
  3163. }
  3164. err = sftpUploadFile(testFilePath, testFileName, testFileSize, client)
  3165. if err != nil {
  3166. t.Errorf("file upload error: %v", err)
  3167. }
  3168. err = client.Chmod(testFileName, 0666)
  3169. if err == nil {
  3170. t.Errorf("chmod without permission should not succeed")
  3171. }
  3172. err = client.Remove(testFileName)
  3173. if err != nil {
  3174. t.Errorf("error removing uploaded file: %v", err)
  3175. }
  3176. os.Remove(testFilePath)
  3177. }
  3178. _, err = httpd.RemoveUser(user, http.StatusOK)
  3179. if err != nil {
  3180. t.Errorf("unable to remove user: %v", err)
  3181. }
  3182. os.RemoveAll(user.GetHomeDir())
  3183. }
  3184. func TestPermChown(t *testing.T) {
  3185. usePubKey := false
  3186. u := getTestUser(usePubKey)
  3187. u.Permissions["/"] = []string{dataprovider.PermListItems, dataprovider.PermDownload, dataprovider.PermUpload, dataprovider.PermDelete,
  3188. dataprovider.PermRename, dataprovider.PermCreateDirs, dataprovider.PermCreateSymlinks, dataprovider.PermOverwrite,
  3189. dataprovider.PermChmod, dataprovider.PermChtimes}
  3190. user, _, err := httpd.AddUser(u, http.StatusOK)
  3191. if err != nil {
  3192. t.Errorf("unable to add user: %v", err)
  3193. }
  3194. client, err := getSftpClient(user, usePubKey)
  3195. if err != nil {
  3196. t.Errorf("unable to create sftp client: %v", err)
  3197. } else {
  3198. defer client.Close()
  3199. testFileName := "test_file.dat"
  3200. testFilePath := filepath.Join(homeBasePath, testFileName)
  3201. testFileSize := int64(65535)
  3202. err = createTestFile(testFilePath, testFileSize)
  3203. if err != nil {
  3204. t.Errorf("unable to create test file: %v", err)
  3205. }
  3206. err = sftpUploadFile(testFilePath, testFileName, testFileSize, client)
  3207. if err != nil {
  3208. t.Errorf("file upload error: %v", err)
  3209. }
  3210. err = client.Chown(testFileName, os.Getuid(), os.Getgid())
  3211. if err == nil {
  3212. t.Errorf("chown without permission should not succeed")
  3213. }
  3214. err = client.Remove(testFileName)
  3215. if err != nil {
  3216. t.Errorf("error removing uploaded file: %v", err)
  3217. }
  3218. os.Remove(testFilePath)
  3219. }
  3220. _, err = httpd.RemoveUser(user, http.StatusOK)
  3221. if err != nil {
  3222. t.Errorf("unable to remove user: %v", err)
  3223. }
  3224. os.RemoveAll(user.GetHomeDir())
  3225. }
  3226. func TestPermChtimes(t *testing.T) {
  3227. usePubKey := false
  3228. u := getTestUser(usePubKey)
  3229. u.Permissions["/"] = []string{dataprovider.PermListItems, dataprovider.PermDownload, dataprovider.PermUpload, dataprovider.PermDelete,
  3230. dataprovider.PermRename, dataprovider.PermCreateDirs, dataprovider.PermCreateSymlinks, dataprovider.PermOverwrite,
  3231. dataprovider.PermChmod, dataprovider.PermChown}
  3232. user, _, err := httpd.AddUser(u, http.StatusOK)
  3233. if err != nil {
  3234. t.Errorf("unable to add user: %v", err)
  3235. }
  3236. client, err := getSftpClient(user, usePubKey)
  3237. if err != nil {
  3238. t.Errorf("unable to create sftp client: %v", err)
  3239. } else {
  3240. defer client.Close()
  3241. testFileName := "test_file.dat"
  3242. testFilePath := filepath.Join(homeBasePath, testFileName)
  3243. testFileSize := int64(65535)
  3244. err = createTestFile(testFilePath, testFileSize)
  3245. if err != nil {
  3246. t.Errorf("unable to create test file: %v", err)
  3247. }
  3248. err = sftpUploadFile(testFilePath, testFileName, testFileSize, client)
  3249. if err != nil {
  3250. t.Errorf("file upload error: %v", err)
  3251. }
  3252. err = client.Chtimes(testFileName, time.Now(), time.Now())
  3253. if err == nil {
  3254. t.Errorf("chtimes without permission should not succeed")
  3255. }
  3256. err = client.Remove(testFileName)
  3257. if err != nil {
  3258. t.Errorf("error removing uploaded file: %v", err)
  3259. }
  3260. os.Remove(testFilePath)
  3261. }
  3262. _, err = httpd.RemoveUser(user, http.StatusOK)
  3263. if err != nil {
  3264. t.Errorf("unable to remove user: %v", err)
  3265. }
  3266. os.RemoveAll(user.GetHomeDir())
  3267. }
  3268. func TestSubDirsUploads(t *testing.T) {
  3269. usePubKey := true
  3270. u := getTestUser(usePubKey)
  3271. u.Permissions["/"] = []string{dataprovider.PermAny}
  3272. u.Permissions["/subdir"] = []string{dataprovider.PermChtimes, dataprovider.PermDownload}
  3273. user, _, err := httpd.AddUser(u, http.StatusOK)
  3274. if err != nil {
  3275. t.Errorf("unable to add user: %v", err)
  3276. }
  3277. client, err := getSftpClient(user, usePubKey)
  3278. if err != nil {
  3279. t.Errorf("unable to create sftp client: %v", err)
  3280. } else {
  3281. defer client.Close()
  3282. err = client.Mkdir("subdir")
  3283. if err != nil {
  3284. t.Errorf("unexpected mkdir error: %v", err)
  3285. }
  3286. testFileName := "test_file.dat"
  3287. testFileNameSub := "/subdir/test_file_dat"
  3288. testFilePath := filepath.Join(homeBasePath, testFileName)
  3289. testFileSize := int64(65535)
  3290. err = createTestFile(testFilePath, testFileSize)
  3291. if err != nil {
  3292. t.Errorf("unable to create test file: %v", err)
  3293. }
  3294. err = sftpUploadFile(testFilePath, testFileName, testFileSize, client)
  3295. if err != nil {
  3296. t.Errorf("file upload error: %v", err)
  3297. }
  3298. err = sftpUploadFile(testFilePath, testFileNameSub, testFileSize, client)
  3299. if !strings.Contains(err.Error(), "Permission Denied") {
  3300. t.Errorf("unexpected upload error: %v", err)
  3301. }
  3302. err = client.Symlink(testFileName, testFileNameSub+".link")
  3303. if !strings.Contains(err.Error(), "Permission Denied") {
  3304. t.Errorf("unexpected upload error: %v", err)
  3305. }
  3306. err = client.Symlink(testFileName, testFileName+".link")
  3307. if err != nil {
  3308. t.Errorf("symlink error: %v", err)
  3309. }
  3310. err = client.Rename(testFileName, testFileNameSub+".rename")
  3311. if !strings.Contains(err.Error(), "Permission Denied") {
  3312. t.Errorf("unexpected rename error: %v", err)
  3313. }
  3314. err = client.Rename(testFileName, testFileName+".rename")
  3315. if err != nil {
  3316. t.Errorf("rename error: %v", err)
  3317. }
  3318. err = client.Remove(testFileNameSub)
  3319. if !strings.Contains(err.Error(), "Permission Denied") {
  3320. t.Errorf("unexpected upload error: %v", err)
  3321. }
  3322. err = client.Remove(testFileName + ".rename")
  3323. if err != nil {
  3324. t.Errorf("remove error: %v", err)
  3325. }
  3326. os.Remove(testFilePath)
  3327. }
  3328. httpd.RemoveUser(user, http.StatusOK)
  3329. os.RemoveAll(user.GetHomeDir())
  3330. }
  3331. func TestSubDirsOverwrite(t *testing.T) {
  3332. usePubKey := true
  3333. u := getTestUser(usePubKey)
  3334. u.Permissions["/"] = []string{dataprovider.PermAny}
  3335. u.Permissions["/subdir"] = []string{dataprovider.PermOverwrite, dataprovider.PermListItems}
  3336. user, _, err := httpd.AddUser(u, http.StatusOK)
  3337. if err != nil {
  3338. t.Errorf("unable to add user: %v", err)
  3339. }
  3340. client, err := getSftpClient(user, usePubKey)
  3341. if err != nil {
  3342. t.Errorf("unable to create sftp client: %v", err)
  3343. } else {
  3344. defer client.Close()
  3345. testFileName := "/subdir/test_file.dat"
  3346. testFilePath := filepath.Join(homeBasePath, "test_file.dat")
  3347. testFileSFTPPath := filepath.Join(u.GetHomeDir(), "subdir", "test_file.dat")
  3348. testFileSize := int64(65535)
  3349. err = createTestFile(testFilePath, testFileSize)
  3350. if err != nil {
  3351. t.Errorf("unable to create test file: %v", err)
  3352. }
  3353. err = createTestFile(testFileSFTPPath, 16384)
  3354. if err != nil {
  3355. t.Errorf("unable to create test file: %v", err)
  3356. }
  3357. err = sftpUploadFile(testFilePath, testFileName+".new", testFileSize, client)
  3358. if !strings.Contains(err.Error(), "Permission Denied") {
  3359. t.Errorf("unexpected upload error: %v", err)
  3360. }
  3361. err = sftpUploadFile(testFilePath, testFileName, testFileSize, client)
  3362. if err != nil {
  3363. t.Errorf("unexpected overwrite error: %v", err)
  3364. }
  3365. os.Remove(testFilePath)
  3366. }
  3367. httpd.RemoveUser(user, http.StatusOK)
  3368. os.RemoveAll(user.GetHomeDir())
  3369. }
  3370. func TestSubDirsDownloads(t *testing.T) {
  3371. usePubKey := true
  3372. u := getTestUser(usePubKey)
  3373. u.Permissions["/"] = []string{dataprovider.PermAny}
  3374. u.Permissions["/subdir"] = []string{dataprovider.PermChmod, dataprovider.PermUpload, dataprovider.PermListItems}
  3375. user, _, err := httpd.AddUser(u, http.StatusOK)
  3376. if err != nil {
  3377. t.Errorf("unable to add user: %v", err)
  3378. }
  3379. client, err := getSftpClient(user, usePubKey)
  3380. if err != nil {
  3381. t.Errorf("unable to create sftp client: %v", err)
  3382. } else {
  3383. defer client.Close()
  3384. err = client.Mkdir("subdir")
  3385. if err != nil {
  3386. t.Errorf("unexpected mkdir error: %v", err)
  3387. }
  3388. testFileName := "/subdir/test_file.dat"
  3389. testFilePath := filepath.Join(homeBasePath, "test_file.dat")
  3390. testFileSize := int64(65535)
  3391. err = createTestFile(testFilePath, testFileSize)
  3392. if err != nil {
  3393. t.Errorf("unable to create test file: %v", err)
  3394. }
  3395. err = sftpUploadFile(testFilePath, testFileName, testFileSize, client)
  3396. if err != nil {
  3397. t.Errorf("file upload error: %v", err)
  3398. }
  3399. localDownloadPath := filepath.Join(homeBasePath, "test_download.dat")
  3400. err = sftpDownloadFile(testFileName, localDownloadPath, testFileSize, client)
  3401. if !strings.Contains(err.Error(), "Permission Denied") {
  3402. t.Errorf("unexpected upload error: %v", err)
  3403. }
  3404. err = sftpUploadFile(testFilePath, testFileName, testFileSize, client)
  3405. if !strings.Contains(err.Error(), "Permission Denied") {
  3406. t.Errorf("unexpected overwrite error: %v", err)
  3407. }
  3408. err = client.Chtimes(testFileName, time.Now(), time.Now())
  3409. if !strings.Contains(err.Error(), "Permission Denied") {
  3410. t.Errorf("unexpected chtimes error: %v", err)
  3411. }
  3412. err = client.Rename(testFileName, testFileName+".rename")
  3413. if !strings.Contains(err.Error(), "Permission Denied") {
  3414. t.Errorf("unexpected rename error: %v", err)
  3415. }
  3416. err = client.Symlink(testFileName, testFileName+".link")
  3417. if !strings.Contains(err.Error(), "Permission Denied") {
  3418. t.Errorf("unexpected symlink error: %v", err)
  3419. }
  3420. err = client.Remove(testFileName)
  3421. if !strings.Contains(err.Error(), "Permission Denied") {
  3422. t.Errorf("unexpected remove error: %v", err)
  3423. }
  3424. os.Remove(localDownloadPath)
  3425. os.Remove(testFilePath)
  3426. }
  3427. httpd.RemoveUser(user, http.StatusOK)
  3428. os.RemoveAll(user.GetHomeDir())
  3429. }
  3430. func TestPermsSubDirsSetstat(t *testing.T) {
  3431. // for setstat we check the parent dir permission if the requested path is a dir
  3432. // otherwise the path permission
  3433. usePubKey := true
  3434. u := getTestUser(usePubKey)
  3435. u.Permissions["/"] = []string{dataprovider.PermListItems, dataprovider.PermCreateDirs}
  3436. u.Permissions["/subdir"] = []string{dataprovider.PermAny}
  3437. user, _, err := httpd.AddUser(u, http.StatusOK)
  3438. if err != nil {
  3439. t.Errorf("unable to add user: %v", err)
  3440. }
  3441. client, err := getSftpClient(user, usePubKey)
  3442. if err != nil {
  3443. t.Errorf("unable to create sftp client: %v", err)
  3444. } else {
  3445. defer client.Close()
  3446. err = client.Mkdir("subdir")
  3447. if err != nil {
  3448. t.Errorf("unexpected mkdir error: %v", err)
  3449. }
  3450. testFileName := "/subdir/test_file.dat"
  3451. testFilePath := filepath.Join(homeBasePath, "test_file.dat")
  3452. testFileSize := int64(65535)
  3453. err = createTestFile(testFilePath, testFileSize)
  3454. if err != nil {
  3455. t.Errorf("unable to create test file: %v", err)
  3456. }
  3457. err = sftpUploadFile(testFilePath, testFileName, testFileSize, client)
  3458. if err != nil {
  3459. t.Errorf("file upload error: %v", err)
  3460. }
  3461. err = client.Chtimes("/subdir/", time.Now(), time.Now())
  3462. if !strings.Contains(err.Error(), "Permission Denied") {
  3463. t.Errorf("unexpected chtimes error: %v", err)
  3464. }
  3465. err = client.Chtimes("subdir/", time.Now(), time.Now())
  3466. if !strings.Contains(err.Error(), "Permission Denied") {
  3467. t.Errorf("unexpected chtimes error: %v", err)
  3468. }
  3469. err = client.Chtimes(testFileName, time.Now(), time.Now())
  3470. if err != nil {
  3471. t.Errorf("unexpected chtimes error: %v", err)
  3472. }
  3473. os.Remove(testFilePath)
  3474. }
  3475. httpd.RemoveUser(user, http.StatusOK)
  3476. os.RemoveAll(user.GetHomeDir())
  3477. }
  3478. func TestPermsSubDirsCommands(t *testing.T) {
  3479. usePubKey := true
  3480. u := getTestUser(usePubKey)
  3481. u.Permissions["/"] = []string{dataprovider.PermAny}
  3482. u.Permissions["/subdir"] = []string{dataprovider.PermDownload, dataprovider.PermUpload}
  3483. user, _, err := httpd.AddUser(u, http.StatusOK)
  3484. if err != nil {
  3485. t.Errorf("unable to add user: %v", err)
  3486. }
  3487. client, err := getSftpClient(user, usePubKey)
  3488. if err != nil {
  3489. t.Errorf("unable to create sftp client: %v", err)
  3490. } else {
  3491. defer client.Close()
  3492. client.Mkdir("subdir")
  3493. acmodTime := time.Now()
  3494. err = client.Chtimes("/subdir", acmodTime, acmodTime)
  3495. if err != nil {
  3496. t.Errorf("unexpected chtimes error: %v", err)
  3497. }
  3498. _, err = client.Stat("/subdir")
  3499. if err != nil {
  3500. t.Errorf("unexpected stat error: %v", err)
  3501. }
  3502. _, err = client.ReadDir("/")
  3503. if err != nil {
  3504. t.Errorf("unexpected readdir error: %v", err)
  3505. }
  3506. _, err = client.ReadDir("/subdir")
  3507. if !strings.Contains(err.Error(), "Permission Denied") {
  3508. t.Errorf("unexpected error: %v", err)
  3509. }
  3510. err = client.RemoveDirectory("/subdir/dir")
  3511. if !strings.Contains(err.Error(), "Permission Denied") {
  3512. t.Errorf("unexpected error: %v", err)
  3513. }
  3514. err = client.Mkdir("/subdir/dir")
  3515. if !strings.Contains(err.Error(), "Permission Denied") {
  3516. t.Errorf("unexpected error: %v", err)
  3517. }
  3518. client.Mkdir("/otherdir")
  3519. err = client.Rename("/otherdir", "/subdir/otherdir")
  3520. if !strings.Contains(err.Error(), "Permission Denied") {
  3521. t.Errorf("unexpected error: %v", err)
  3522. }
  3523. err = client.Symlink("/otherdir", "/subdir/otherdir")
  3524. if !strings.Contains(err.Error(), "Permission Denied") {
  3525. t.Errorf("unexpected error: %v", err)
  3526. }
  3527. err = client.Symlink("/otherdir", "/otherdir_link")
  3528. if err != nil {
  3529. t.Errorf("unexpected rename dir error: %v", err)
  3530. }
  3531. err = client.Rename("/otherdir", "/otherdir1")
  3532. if err != nil {
  3533. t.Errorf("unexpected rename dir error: %v", err)
  3534. }
  3535. err = client.RemoveDirectory("/subdir")
  3536. if err != nil {
  3537. t.Errorf("unexpected remove dir error: %v", err)
  3538. }
  3539. }
  3540. httpd.RemoveUser(user, http.StatusOK)
  3541. os.RemoveAll(user.GetHomeDir())
  3542. }
  3543. func TestRootDirCommands(t *testing.T) {
  3544. usePubKey := true
  3545. u := getTestUser(usePubKey)
  3546. u.Permissions["/"] = []string{dataprovider.PermAny}
  3547. u.Permissions["/subdir"] = []string{dataprovider.PermDownload, dataprovider.PermUpload}
  3548. user, _, err := httpd.AddUser(u, http.StatusOK)
  3549. if err != nil {
  3550. t.Errorf("unable to add user: %v", err)
  3551. }
  3552. client, err := getSftpClient(user, usePubKey)
  3553. if err != nil {
  3554. t.Errorf("unable to create sftp client: %v", err)
  3555. } else {
  3556. defer client.Close()
  3557. err = client.Rename("/", "rootdir")
  3558. if !strings.Contains(err.Error(), "Permission Denied") {
  3559. t.Errorf("unexpected error renaming root dir: %v", err)
  3560. }
  3561. err = client.Symlink("/", "rootdir")
  3562. if !strings.Contains(err.Error(), "Permission Denied") {
  3563. t.Errorf("unexpected error symlinking root dir: %v", err)
  3564. }
  3565. err = client.RemoveDirectory("/")
  3566. if !strings.Contains(err.Error(), "Permission Denied") {
  3567. t.Errorf("unexpected error removing root dir: %v", err)
  3568. }
  3569. }
  3570. httpd.RemoveUser(user, http.StatusOK)
  3571. os.RemoveAll(user.GetHomeDir())
  3572. }
  3573. func TestRelativePaths(t *testing.T) {
  3574. user := getTestUser(true)
  3575. var path, rel string
  3576. filesystems := []vfs.Fs{vfs.NewOsFs("", user.GetHomeDir(), user.VirtualFolders)}
  3577. keyPrefix := strings.TrimPrefix(user.GetHomeDir(), "/") + "/"
  3578. s3config := vfs.S3FsConfig{
  3579. KeyPrefix: keyPrefix,
  3580. }
  3581. s3fs, _ := vfs.NewS3Fs("", user.GetHomeDir(), s3config)
  3582. gcsConfig := vfs.GCSFsConfig{
  3583. KeyPrefix: keyPrefix,
  3584. }
  3585. gcsfs, _ := vfs.NewGCSFs("", user.GetHomeDir(), gcsConfig)
  3586. if runtime.GOOS != "windows" {
  3587. filesystems = append(filesystems, s3fs, gcsfs)
  3588. }
  3589. for _, fs := range filesystems {
  3590. path = filepath.Join(user.HomeDir, "/")
  3591. rel = fs.GetRelativePath(path)
  3592. if rel != "/" {
  3593. t.Errorf("Unexpected relative path: %v fs: %v", rel, fs.Name())
  3594. }
  3595. path = filepath.Join(user.HomeDir, "//")
  3596. rel = fs.GetRelativePath(path)
  3597. if rel != "/" {
  3598. t.Errorf("Unexpected relative path: %v fs: %v", rel, fs.Name())
  3599. }
  3600. path = filepath.Join(user.HomeDir, "../..")
  3601. rel = fs.GetRelativePath(path)
  3602. if rel != "/" {
  3603. t.Errorf("Unexpected relative path: %v path: %v fs: %v", rel, path, fs.Name())
  3604. }
  3605. path = filepath.Join(user.HomeDir, "../../../../../")
  3606. rel = fs.GetRelativePath(path)
  3607. if rel != "/" {
  3608. t.Errorf("Unexpected relative path: %v fs: %v", rel, fs.Name())
  3609. }
  3610. path = filepath.Join(user.HomeDir, "/..")
  3611. rel = fs.GetRelativePath(path)
  3612. if rel != "/" {
  3613. t.Errorf("Unexpected relative path: %v path: %v fs: %v", rel, path, fs.Name())
  3614. }
  3615. path = filepath.Join(user.HomeDir, "/../../../..")
  3616. rel = fs.GetRelativePath(path)
  3617. if rel != "/" {
  3618. t.Errorf("Unexpected relative path: %v fs: %v", rel, fs.Name())
  3619. }
  3620. path = filepath.Join(user.HomeDir, "")
  3621. rel = fs.GetRelativePath(path)
  3622. if rel != "/" {
  3623. t.Errorf("Unexpected relative path: %v fs: %v", rel, fs.Name())
  3624. }
  3625. path = filepath.Join(user.HomeDir, ".")
  3626. rel = fs.GetRelativePath(path)
  3627. if rel != "/" {
  3628. t.Errorf("Unexpected relative path: %v fs: %v", rel, fs.Name())
  3629. }
  3630. path = filepath.Join(user.HomeDir, "somedir")
  3631. rel = fs.GetRelativePath(path)
  3632. if rel != "/somedir" {
  3633. t.Errorf("Unexpected relative path: %v fs: %v", rel, fs.Name())
  3634. }
  3635. path = filepath.Join(user.HomeDir, "/somedir/subdir")
  3636. rel = fs.GetRelativePath(path)
  3637. if rel != "/somedir/subdir" {
  3638. t.Errorf("Unexpected relative path: %v fs: %v", rel, fs.Name())
  3639. }
  3640. }
  3641. }
  3642. func TestResolvePaths(t *testing.T) {
  3643. user := getTestUser(true)
  3644. var path, resolved string
  3645. var err error
  3646. filesystems := []vfs.Fs{vfs.NewOsFs("", user.GetHomeDir(), user.VirtualFolders)}
  3647. keyPrefix := strings.TrimPrefix(user.GetHomeDir(), "/") + "/"
  3648. s3config := vfs.S3FsConfig{
  3649. KeyPrefix: keyPrefix,
  3650. }
  3651. os.MkdirAll(user.GetHomeDir(), 0777)
  3652. s3fs, _ := vfs.NewS3Fs("", user.GetHomeDir(), s3config)
  3653. gcsConfig := vfs.GCSFsConfig{
  3654. KeyPrefix: keyPrefix,
  3655. }
  3656. gcsfs, _ := vfs.NewGCSFs("", user.GetHomeDir(), gcsConfig)
  3657. if runtime.GOOS != "windows" {
  3658. filesystems = append(filesystems, s3fs, gcsfs)
  3659. }
  3660. for _, fs := range filesystems {
  3661. path = "/"
  3662. resolved, _ = fs.ResolvePath(filepath.ToSlash(path))
  3663. if resolved != fs.Join(user.GetHomeDir(), "/") {
  3664. t.Errorf("Unexpected resolved path: %v for: %v, fs: %v", resolved, path, fs.Name())
  3665. }
  3666. path = "."
  3667. resolved, _ = fs.ResolvePath(filepath.ToSlash(path))
  3668. if resolved != fs.Join(user.GetHomeDir(), "/") {
  3669. t.Errorf("Unexpected resolved path: %v for: %v, fs: %v", resolved, path, fs.Name())
  3670. }
  3671. path = "test/sub"
  3672. resolved, _ = fs.ResolvePath(filepath.ToSlash(path))
  3673. if resolved != fs.Join(user.GetHomeDir(), "/test/sub") {
  3674. t.Errorf("Unexpected resolved path: %v for: %v, fs: %v", resolved, path, fs.Name())
  3675. }
  3676. path = "../test/sub"
  3677. resolved, err = fs.ResolvePath(filepath.ToSlash(path))
  3678. if vfs.IsLocalOsFs(fs) {
  3679. if err == nil {
  3680. t.Errorf("Unexpected resolved path: %v for: %v, fs: %v", resolved, path, fs.Name())
  3681. }
  3682. } else {
  3683. if resolved != fs.Join(user.GetHomeDir(), "/test/sub") && err == nil {
  3684. t.Errorf("Unexpected resolved path: %v for: %v, fs: %v", resolved, path, fs.Name())
  3685. }
  3686. }
  3687. path = "../../../test/../sub"
  3688. resolved, err = fs.ResolvePath(filepath.ToSlash(path))
  3689. if vfs.IsLocalOsFs(fs) {
  3690. if err == nil {
  3691. t.Errorf("Unexpected resolved path: %v for: %v, fs: %v", resolved, path, fs.Name())
  3692. }
  3693. } else {
  3694. if resolved != fs.Join(user.GetHomeDir(), "/sub") && err == nil {
  3695. t.Errorf("Unexpected resolved path: %v for: %v, fs: %v", resolved, path, fs.Name())
  3696. }
  3697. }
  3698. }
  3699. os.RemoveAll(user.GetHomeDir())
  3700. }
  3701. func TestVirtualRelativePaths(t *testing.T) {
  3702. user := getTestUser(true)
  3703. mappedPath := filepath.Join(os.TempDir(), "vdir")
  3704. vdirPath := "/vdir"
  3705. user.VirtualFolders = append(user.VirtualFolders, vfs.VirtualFolder{
  3706. VirtualPath: vdirPath,
  3707. MappedPath: mappedPath,
  3708. })
  3709. os.MkdirAll(mappedPath, 0777)
  3710. fs := vfs.NewOsFs("", user.GetHomeDir(), user.VirtualFolders)
  3711. rel := fs.GetRelativePath(mappedPath)
  3712. if rel != vdirPath {
  3713. t.Errorf("Unexpected relative path: %v", rel)
  3714. }
  3715. rel = fs.GetRelativePath(filepath.Join(mappedPath, ".."))
  3716. if rel != "/" {
  3717. t.Errorf("Unexpected relative path: %v", rel)
  3718. }
  3719. // path outside home and virtual dir
  3720. rel = fs.GetRelativePath(filepath.Join(mappedPath, "../vdir1"))
  3721. if rel != "/" {
  3722. t.Errorf("Unexpected relative path: %v", rel)
  3723. }
  3724. rel = fs.GetRelativePath(filepath.Join(mappedPath, "../vdir/file.txt"))
  3725. if rel != "/vdir/file.txt" {
  3726. t.Errorf("Unexpected relative path: %v", rel)
  3727. }
  3728. rel = fs.GetRelativePath(filepath.Join(user.HomeDir, "vdir1/file.txt"))
  3729. if rel != "/vdir1/file.txt" {
  3730. t.Errorf("Unexpected relative path: %v", rel)
  3731. }
  3732. }
  3733. func TestResolveVirtualPaths(t *testing.T) {
  3734. user := getTestUser(true)
  3735. mappedPath := filepath.Join(os.TempDir(), "vdir")
  3736. vdirPath := "/vdir"
  3737. user.VirtualFolders = append(user.VirtualFolders, vfs.VirtualFolder{
  3738. VirtualPath: vdirPath,
  3739. MappedPath: mappedPath,
  3740. })
  3741. os.MkdirAll(mappedPath, 0777)
  3742. fs := vfs.NewOsFs("", user.GetHomeDir(), user.VirtualFolders)
  3743. osFs := fs.(*vfs.OsFs)
  3744. b, f := osFs.GetFsPaths("/vdir/a.txt")
  3745. if b != mappedPath {
  3746. t.Errorf("unexpected base path: %#v expected: %#v", b, mappedPath)
  3747. }
  3748. if f != filepath.Join(mappedPath, "a.txt") {
  3749. t.Errorf("unexpected fs path: %#v expected: %#v", f, filepath.Join(mappedPath, "a.txt"))
  3750. }
  3751. b, f = osFs.GetFsPaths("/vdir/sub with space & spécial chars/a.txt")
  3752. if b != mappedPath {
  3753. t.Errorf("unexpected base path: %#v expected: %#v", b, mappedPath)
  3754. }
  3755. if f != filepath.Join(mappedPath, "sub with space & spécial chars/a.txt") {
  3756. t.Errorf("unexpected fs path: %#v expected: %#v", f, filepath.Join(mappedPath, "sub with space & spécial chars/a.txt"))
  3757. }
  3758. b, f = osFs.GetFsPaths("/vdir/../a.txt")
  3759. if b != user.GetHomeDir() {
  3760. t.Errorf("unexpected base path: %#v expected: %#v", b, user.GetHomeDir())
  3761. }
  3762. if f != filepath.Join(user.GetHomeDir(), "a.txt") {
  3763. t.Errorf("unexpected fs path: %#v expected: %#v", f, filepath.Join(user.GetHomeDir(), "a.txt"))
  3764. }
  3765. b, f = osFs.GetFsPaths("/vdir1/a.txt")
  3766. if b != user.GetHomeDir() {
  3767. t.Errorf("unexpected base path: %#v expected: %#v", b, user.GetHomeDir())
  3768. }
  3769. if f != filepath.Join(user.GetHomeDir(), "/vdir1/a.txt") {
  3770. t.Errorf("unexpected fs path: %#v expected: %#v", f, filepath.Join(user.GetHomeDir(), "/vdir1/a.txt"))
  3771. }
  3772. }
  3773. func TestUserPerms(t *testing.T) {
  3774. user := getTestUser(true)
  3775. user.Permissions = make(map[string][]string)
  3776. user.Permissions["/"] = []string{dataprovider.PermListItems}
  3777. user.Permissions["/p"] = []string{dataprovider.PermDelete}
  3778. user.Permissions["/p/1"] = []string{dataprovider.PermDownload, dataprovider.PermUpload}
  3779. user.Permissions["/p/2"] = []string{dataprovider.PermCreateDirs}
  3780. user.Permissions["/p/3"] = []string{dataprovider.PermChmod}
  3781. user.Permissions["/p/3/4"] = []string{dataprovider.PermChtimes}
  3782. user.Permissions["/tmp"] = []string{dataprovider.PermRename}
  3783. if !user.HasPerm(dataprovider.PermListItems, "/") {
  3784. t.Error("expected permission not found")
  3785. }
  3786. if !user.HasPerm(dataprovider.PermListItems, ".") {
  3787. t.Error("expected permission not found")
  3788. }
  3789. if !user.HasPerm(dataprovider.PermListItems, "") {
  3790. t.Error("expected permission not found")
  3791. }
  3792. if !user.HasPerm(dataprovider.PermListItems, "../") {
  3793. t.Error("expected permission not found")
  3794. }
  3795. // path p and /p are the same
  3796. if !user.HasPerm(dataprovider.PermDelete, "/p") {
  3797. t.Error("expected permission not found")
  3798. }
  3799. if !user.HasPerm(dataprovider.PermDownload, "/p/1") {
  3800. t.Error("expected permission not found")
  3801. }
  3802. if !user.HasPerm(dataprovider.PermCreateDirs, "p/2") {
  3803. t.Error("expected permission not found")
  3804. }
  3805. if !user.HasPerm(dataprovider.PermChmod, "/p/3") {
  3806. t.Error("expected permission not found")
  3807. }
  3808. if !user.HasPerm(dataprovider.PermChtimes, "p/3/4/") {
  3809. t.Error("expected permission not found")
  3810. }
  3811. if !user.HasPerm(dataprovider.PermChtimes, "p/3/4/../4") {
  3812. t.Error("expected permission not found")
  3813. }
  3814. // undefined paths have permissions of the nearest path
  3815. if !user.HasPerm(dataprovider.PermListItems, "/p34") {
  3816. t.Error("expected permission not found")
  3817. }
  3818. if !user.HasPerm(dataprovider.PermListItems, "/p34/p1/file.dat") {
  3819. t.Error("expected permission not found")
  3820. }
  3821. if !user.HasPerm(dataprovider.PermChtimes, "/p/3/4/5/6") {
  3822. t.Error("expected permission not found")
  3823. }
  3824. if !user.HasPerm(dataprovider.PermDownload, "/p/1/test/file.dat") {
  3825. t.Error("expected permission not found")
  3826. }
  3827. }
  3828. func TestFilterFileExtensions(t *testing.T) {
  3829. user := getTestUser(true)
  3830. extension := dataprovider.ExtensionsFilter{
  3831. Path: "/test",
  3832. AllowedExtensions: []string{".jpg", ".png"},
  3833. DeniedExtensions: []string{".pdf"},
  3834. }
  3835. filters := dataprovider.UserFilters{
  3836. FileExtensions: []dataprovider.ExtensionsFilter{extension},
  3837. }
  3838. user.Filters = filters
  3839. if !user.IsFileAllowed("/test/test.jPg") {
  3840. t.Error("this file must be allowed")
  3841. }
  3842. if user.IsFileAllowed("/test/test.pdf") {
  3843. t.Error("this file must be denied")
  3844. }
  3845. if !user.IsFileAllowed("/test.pDf") {
  3846. t.Error("this file must be allowed")
  3847. }
  3848. filters.FileExtensions = append(filters.FileExtensions, dataprovider.ExtensionsFilter{
  3849. Path: "/",
  3850. AllowedExtensions: []string{".zip", ".rar", ".pdf"},
  3851. DeniedExtensions: []string{".gz"},
  3852. })
  3853. user.Filters = filters
  3854. if user.IsFileAllowed("/test1/test.gz") {
  3855. t.Error("this file must be denied")
  3856. }
  3857. if !user.IsFileAllowed("/test1/test.zip") {
  3858. t.Error("this file must be allowed")
  3859. }
  3860. if user.IsFileAllowed("/test/sub/test.pdf") {
  3861. t.Error("this file must be denied")
  3862. }
  3863. if user.IsFileAllowed("/test1/test.png") {
  3864. t.Error("this file must be denied")
  3865. }
  3866. filters.FileExtensions = append(filters.FileExtensions, dataprovider.ExtensionsFilter{
  3867. Path: "/test/sub",
  3868. DeniedExtensions: []string{".tar"},
  3869. })
  3870. user.Filters = filters
  3871. if user.IsFileAllowed("/test/sub/sub/test.tar") {
  3872. t.Error("this file must be denied")
  3873. }
  3874. if !user.IsFileAllowed("/test/sub/test.gz") {
  3875. t.Error("this file must be allowed")
  3876. }
  3877. if user.IsFileAllowed("/test/test.zip") {
  3878. t.Error("this file must be denied")
  3879. }
  3880. }
  3881. func TestUserAllowedLoginMethods(t *testing.T) {
  3882. user := getTestUser(true)
  3883. user.Filters.DeniedLoginMethods = dataprovider.ValidSSHLoginMethods
  3884. allowedMethods := user.GetAllowedLoginMethods()
  3885. if len(allowedMethods) != 0 {
  3886. t.Errorf("unexpected allowed methods: %+v", allowedMethods)
  3887. }
  3888. user.Filters.DeniedLoginMethods = []string{
  3889. dataprovider.SSHLoginMethodPassword,
  3890. dataprovider.SSHLoginMethodPublicKey,
  3891. dataprovider.SSHLoginMethodKeyboardInteractive,
  3892. }
  3893. allowedMethods = user.GetAllowedLoginMethods()
  3894. if len(allowedMethods) != 2 {
  3895. t.Errorf("unexpected allowed methods: %+v", allowedMethods)
  3896. }
  3897. if !utils.IsStringInSlice(dataprovider.SSHLoginMethodKeyAndKeyboardInt, allowedMethods) {
  3898. t.Errorf("unexpected allowed methods: %+v", allowedMethods)
  3899. }
  3900. if !utils.IsStringInSlice(dataprovider.SSHLoginMethodKeyAndPassword, allowedMethods) {
  3901. t.Errorf("unexpected allowed methods: %+v", allowedMethods)
  3902. }
  3903. }
  3904. func TestUserPartialAuth(t *testing.T) {
  3905. user := getTestUser(true)
  3906. user.Filters.DeniedLoginMethods = []string{
  3907. dataprovider.SSHLoginMethodPassword,
  3908. dataprovider.SSHLoginMethodPublicKey,
  3909. dataprovider.SSHLoginMethodKeyboardInteractive,
  3910. }
  3911. if user.IsPartialAuth(dataprovider.SSHLoginMethodPassword) {
  3912. t.Error("unexpected partial auth method")
  3913. }
  3914. if user.IsPartialAuth(dataprovider.SSHLoginMethodKeyboardInteractive) {
  3915. t.Error("unexpected partial auth method")
  3916. }
  3917. if !user.IsPartialAuth(dataprovider.SSHLoginMethodPublicKey) {
  3918. t.Error("public key must be a partial auth method with this configuration")
  3919. }
  3920. user.Filters.DeniedLoginMethods = []string{
  3921. dataprovider.SSHLoginMethodPassword,
  3922. dataprovider.SSHLoginMethodKeyboardInteractive,
  3923. }
  3924. if user.IsPartialAuth(dataprovider.SSHLoginMethodPublicKey) {
  3925. t.Error("public key must not be a partial auth method with this configuration")
  3926. }
  3927. user.Filters.DeniedLoginMethods = []string{
  3928. dataprovider.SSHLoginMethodPassword,
  3929. dataprovider.SSHLoginMethodPublicKey,
  3930. }
  3931. if user.IsPartialAuth(dataprovider.SSHLoginMethodPublicKey) {
  3932. t.Error("public key must not be a partial auth method with this configuration")
  3933. }
  3934. }
  3935. func TestUserGetNextAuthMethods(t *testing.T) {
  3936. user := getTestUser(true)
  3937. user.Filters.DeniedLoginMethods = []string{
  3938. dataprovider.SSHLoginMethodPassword,
  3939. dataprovider.SSHLoginMethodPublicKey,
  3940. dataprovider.SSHLoginMethodKeyboardInteractive,
  3941. }
  3942. methods := user.GetNextAuthMethods(nil)
  3943. if len(methods) != 0 {
  3944. t.Errorf("unexpected next auth methods: %+v", methods)
  3945. }
  3946. methods = user.GetNextAuthMethods([]string{dataprovider.SSHLoginMethodPassword})
  3947. if len(methods) != 0 {
  3948. t.Errorf("unexpected next auth methods: %+v", methods)
  3949. }
  3950. methods = user.GetNextAuthMethods([]string{dataprovider.SSHLoginMethodKeyboardInteractive})
  3951. if len(methods) != 0 {
  3952. t.Errorf("unexpected next auth methods: %+v", methods)
  3953. }
  3954. methods = user.GetNextAuthMethods([]string{
  3955. dataprovider.SSHLoginMethodPublicKey,
  3956. dataprovider.SSHLoginMethodKeyboardInteractive,
  3957. })
  3958. if len(methods) != 0 {
  3959. t.Errorf("unexpected next auth methods: %+v", methods)
  3960. }
  3961. methods = user.GetNextAuthMethods([]string{dataprovider.SSHLoginMethodPublicKey})
  3962. if len(methods) != 2 {
  3963. t.Errorf("unexpected next auth methods: %+v", methods)
  3964. }
  3965. if !utils.IsStringInSlice(dataprovider.SSHLoginMethodPassword, methods) {
  3966. t.Errorf("unexpected next auth methods: %+v", methods)
  3967. }
  3968. if !utils.IsStringInSlice(dataprovider.SSHLoginMethodKeyboardInteractive, methods) {
  3969. t.Errorf("unexpected next auth methods: %+v", methods)
  3970. }
  3971. user.Filters.DeniedLoginMethods = []string{
  3972. dataprovider.SSHLoginMethodPassword,
  3973. dataprovider.SSHLoginMethodPublicKey,
  3974. dataprovider.SSHLoginMethodKeyboardInteractive,
  3975. dataprovider.SSHLoginMethodKeyAndKeyboardInt,
  3976. }
  3977. methods = user.GetNextAuthMethods([]string{dataprovider.SSHLoginMethodPublicKey})
  3978. if len(methods) != 1 {
  3979. t.Errorf("unexpected next auth methods: %+v", methods)
  3980. }
  3981. if !utils.IsStringInSlice(dataprovider.SSHLoginMethodPassword, methods) {
  3982. t.Errorf("unexpected next auth methods: %+v", methods)
  3983. }
  3984. user.Filters.DeniedLoginMethods = []string{
  3985. dataprovider.SSHLoginMethodPassword,
  3986. dataprovider.SSHLoginMethodPublicKey,
  3987. dataprovider.SSHLoginMethodKeyboardInteractive,
  3988. dataprovider.SSHLoginMethodKeyAndPassword,
  3989. }
  3990. methods = user.GetNextAuthMethods([]string{dataprovider.SSHLoginMethodPublicKey})
  3991. if len(methods) != 1 {
  3992. t.Errorf("unexpected next auth methods: %+v", methods)
  3993. }
  3994. if !utils.IsStringInSlice(dataprovider.SSHLoginMethodKeyboardInteractive, methods) {
  3995. t.Errorf("unexpected next auth methods: %+v", methods)
  3996. }
  3997. }
  3998. func TestUserIsLoginMethodAllowed(t *testing.T) {
  3999. user := getTestUser(true)
  4000. user.Filters.DeniedLoginMethods = []string{
  4001. dataprovider.SSHLoginMethodPassword,
  4002. dataprovider.SSHLoginMethodPublicKey,
  4003. dataprovider.SSHLoginMethodKeyboardInteractive,
  4004. }
  4005. if user.IsLoginMethodAllowed(dataprovider.SSHLoginMethodPassword, nil) {
  4006. t.Error("unexpected login method allowed")
  4007. }
  4008. if !user.IsLoginMethodAllowed(dataprovider.SSHLoginMethodPassword, []string{dataprovider.SSHLoginMethodPublicKey}) {
  4009. t.Error("unexpected login method denied")
  4010. }
  4011. if !user.IsLoginMethodAllowed(dataprovider.SSHLoginMethodKeyboardInteractive, []string{dataprovider.SSHLoginMethodPublicKey}) {
  4012. t.Error("unexpected login method denied")
  4013. }
  4014. user.Filters.DeniedLoginMethods = []string{
  4015. dataprovider.SSHLoginMethodPublicKey,
  4016. dataprovider.SSHLoginMethodKeyboardInteractive,
  4017. }
  4018. if !user.IsLoginMethodAllowed(dataprovider.SSHLoginMethodPassword, nil) {
  4019. t.Error("unexpected login method denied")
  4020. }
  4021. }
  4022. func TestUserEmptySubDirPerms(t *testing.T) {
  4023. user := getTestUser(true)
  4024. user.Permissions = make(map[string][]string)
  4025. user.Permissions["/emptyperms"] = []string{}
  4026. for _, p := range dataprovider.ValidPerms {
  4027. if user.HasPerm(p, "/emptyperms") {
  4028. t.Errorf("unexpected permission %#v for dir /emptyperms", p)
  4029. }
  4030. }
  4031. }
  4032. func TestUserFiltersIPMaskConditions(t *testing.T) {
  4033. user := getTestUser(true)
  4034. // with no filter login must be allowed even if the remoteIP is invalid
  4035. if !user.IsLoginFromAddrAllowed("192.168.1.5") {
  4036. t.Error("unexpected login denied")
  4037. }
  4038. if !user.IsLoginFromAddrAllowed("invalid") {
  4039. t.Error("unexpected login denied")
  4040. }
  4041. user.Filters.DeniedIP = append(user.Filters.DeniedIP, "192.168.1.0/24")
  4042. if user.IsLoginFromAddrAllowed("192.168.1.5") {
  4043. t.Error("unexpected login allowed")
  4044. }
  4045. if !user.IsLoginFromAddrAllowed("192.168.2.6") {
  4046. t.Error("unexpected login denied")
  4047. }
  4048. user.Filters.AllowedIP = append(user.Filters.AllowedIP, "192.168.1.5/32")
  4049. // if the same ip/mask is both denied and allowed then login must be denied
  4050. if user.IsLoginFromAddrAllowed("192.168.1.5") {
  4051. t.Error("unexpected login allowed")
  4052. }
  4053. if user.IsLoginFromAddrAllowed("192.168.3.6") {
  4054. t.Error("unexpected login allowed")
  4055. }
  4056. user.Filters.DeniedIP = []string{}
  4057. if !user.IsLoginFromAddrAllowed("192.168.1.5") {
  4058. t.Error("unexpected login denied")
  4059. }
  4060. if user.IsLoginFromAddrAllowed("192.168.1.6") {
  4061. t.Error("unexpected login allowed")
  4062. }
  4063. user.Filters.DeniedIP = []string{"192.168.0.0/16", "172.16.0.0/16"}
  4064. user.Filters.AllowedIP = []string{}
  4065. if user.IsLoginFromAddrAllowed("192.168.5.255") {
  4066. t.Error("unexpected login allowed")
  4067. }
  4068. if user.IsLoginFromAddrAllowed("172.16.1.2") {
  4069. t.Error("unexpected login allowed")
  4070. }
  4071. if !user.IsLoginFromAddrAllowed("172.18.2.1") {
  4072. t.Error("unexpected login denied")
  4073. }
  4074. user.Filters.AllowedIP = []string{"10.4.4.0/24"}
  4075. if user.IsLoginFromAddrAllowed("10.5.4.2") {
  4076. t.Error("unexpected login allowed")
  4077. }
  4078. if !user.IsLoginFromAddrAllowed("10.4.4.2") {
  4079. t.Error("unexpected login denied")
  4080. }
  4081. if !user.IsLoginFromAddrAllowed("invalid") {
  4082. t.Error("unexpected login denied")
  4083. }
  4084. }
  4085. func TestSSHCommands(t *testing.T) {
  4086. usePubKey := false
  4087. user, _, err := httpd.AddUser(getTestUser(usePubKey), http.StatusOK)
  4088. if err != nil {
  4089. t.Errorf("unable to add user: %v", err)
  4090. }
  4091. _, err = runSSHCommand("ls", user, usePubKey)
  4092. if err == nil {
  4093. t.Errorf("unsupported ssh command must fail")
  4094. }
  4095. _, err = runSSHCommand("cd", user, usePubKey)
  4096. if err != nil {
  4097. t.Errorf("unexpected error for ssh cd command: %v", err)
  4098. }
  4099. out, err := runSSHCommand("pwd", user, usePubKey)
  4100. if err != nil {
  4101. t.Errorf("unexpected error: %v", err)
  4102. t.Fail()
  4103. }
  4104. if string(out) != "/\n" {
  4105. t.Errorf("invalid response for ssh pwd command: %v", string(out))
  4106. }
  4107. out, err = runSSHCommand("md5sum", user, usePubKey)
  4108. if err != nil {
  4109. t.Errorf("unexpected error: %v", err)
  4110. t.Fail()
  4111. }
  4112. // echo -n '' | md5sum
  4113. if !strings.Contains(string(out), "d41d8cd98f00b204e9800998ecf8427e") {
  4114. t.Errorf("invalid md5sum: %v", string(out))
  4115. }
  4116. out, err = runSSHCommand("sha1sum", user, usePubKey)
  4117. if err != nil {
  4118. t.Errorf("unexpected error: %v", err)
  4119. t.Fail()
  4120. }
  4121. if !strings.Contains(string(out), "da39a3ee5e6b4b0d3255bfef95601890afd80709") {
  4122. t.Errorf("invalid sha1sum: %v", string(out))
  4123. }
  4124. out, err = runSSHCommand("sha256sum", user, usePubKey)
  4125. if err != nil {
  4126. t.Errorf("unexpected error: %v", err)
  4127. t.Fail()
  4128. }
  4129. if !strings.Contains(string(out), "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855") {
  4130. t.Errorf("invalid sha256sum: %v", string(out))
  4131. }
  4132. out, err = runSSHCommand("sha384sum", user, usePubKey)
  4133. if err != nil {
  4134. t.Errorf("unexpected error: %v", err)
  4135. t.Fail()
  4136. }
  4137. if !strings.Contains(string(out), "38b060a751ac96384cd9327eb1b1e36a21fdb71114be07434c0cc7bf63f6e1da274edebfe76f65fbd51ad2f14898b95b") {
  4138. t.Errorf("invalid sha384sum: %v", string(out))
  4139. }
  4140. _, err = httpd.RemoveUser(user, http.StatusOK)
  4141. if err != nil {
  4142. t.Errorf("unable to remove user: %v", err)
  4143. }
  4144. }
  4145. func TestSSHFileHash(t *testing.T) {
  4146. usePubKey := true
  4147. user, _, err := httpd.AddUser(getTestUser(usePubKey), http.StatusOK)
  4148. if err != nil {
  4149. t.Errorf("unable to add user: %v", err)
  4150. }
  4151. client, err := getSftpClient(user, usePubKey)
  4152. if err != nil {
  4153. t.Errorf("unable to create sftp client: %v", err)
  4154. } else {
  4155. defer client.Close()
  4156. testFileName := "test_file.dat"
  4157. testFilePath := filepath.Join(homeBasePath, testFileName)
  4158. testFileSize := int64(65535)
  4159. err = createTestFile(testFilePath, testFileSize)
  4160. if err != nil {
  4161. t.Errorf("unable to create test file: %v", err)
  4162. }
  4163. err = sftpUploadFile(testFilePath, testFileName, testFileSize, client)
  4164. if err != nil {
  4165. t.Errorf("file upload error: %v", err)
  4166. }
  4167. user.Permissions = make(map[string][]string)
  4168. user.Permissions["/"] = []string{dataprovider.PermUpload}
  4169. _, _, err = httpd.UpdateUser(user, http.StatusOK)
  4170. if err != nil {
  4171. t.Errorf("unable to update user: %v", err)
  4172. }
  4173. _, err = runSSHCommand("sha512sum "+testFileName, user, usePubKey)
  4174. if err == nil {
  4175. t.Errorf("hash command with no list permission must fail")
  4176. }
  4177. user.Permissions["/"] = []string{dataprovider.PermAny}
  4178. _, _, err = httpd.UpdateUser(user, http.StatusOK)
  4179. if err != nil {
  4180. t.Errorf("unable to update user: %v", err)
  4181. }
  4182. initialHash, err := computeHashForFile(sha512.New(), testFilePath)
  4183. if err != nil {
  4184. t.Errorf("error computing file hash: %v", err)
  4185. }
  4186. out, err := runSSHCommand("sha512sum "+testFileName, user, usePubKey)
  4187. if err != nil {
  4188. t.Errorf("unexpected error: %v", err)
  4189. t.Fail()
  4190. }
  4191. if !strings.Contains(string(out), initialHash) {
  4192. t.Errorf("invalid sha512sum: %v", string(out))
  4193. }
  4194. _, err = runSSHCommand("sha512sum invalid_path", user, usePubKey)
  4195. if err == nil {
  4196. t.Errorf("hash for an invalid path must fail")
  4197. }
  4198. os.Remove(testFilePath)
  4199. }
  4200. _, err = httpd.RemoveUser(user, http.StatusOK)
  4201. if err != nil {
  4202. t.Errorf("unable to remove user: %v", err)
  4203. }
  4204. os.RemoveAll(user.GetHomeDir())
  4205. }
  4206. func TestBasicGitCommands(t *testing.T) {
  4207. if len(gitPath) == 0 || len(sshPath) == 0 {
  4208. t.Skip("git and/or ssh command not found, unable to execute this test")
  4209. }
  4210. usePubKey := true
  4211. u := getTestUser(usePubKey)
  4212. user, _, err := httpd.AddUser(u, http.StatusOK)
  4213. if err != nil {
  4214. t.Errorf("unable to add user: %v", err)
  4215. }
  4216. repoName := "testrepo"
  4217. clonePath := filepath.Join(homeBasePath, repoName)
  4218. os.RemoveAll(user.GetHomeDir())
  4219. os.RemoveAll(filepath.Join(homeBasePath, repoName))
  4220. out, err := initGitRepo(filepath.Join(user.HomeDir, repoName))
  4221. if err != nil {
  4222. t.Errorf("unexpected error: %v out: %v", err, string(out))
  4223. }
  4224. out, err = cloneGitRepo(homeBasePath, "/"+repoName, user.Username)
  4225. if err != nil {
  4226. t.Errorf("unexpected error: %v out: %v", err, string(out))
  4227. }
  4228. out, err = addFileToGitRepo(clonePath, 128)
  4229. if err != nil {
  4230. t.Errorf("unexpected error: %v out: %v", err, string(out))
  4231. }
  4232. user.QuotaFiles = 100000
  4233. _, _, err = httpd.UpdateUser(user, http.StatusOK)
  4234. if err != nil {
  4235. t.Errorf("unable to update user: %v", err)
  4236. }
  4237. out, err = pushToGitRepo(clonePath)
  4238. if err != nil {
  4239. t.Errorf("unexpected error: %v out: %v", err, string(out))
  4240. printLatestLogs(10)
  4241. }
  4242. err = waitQuotaScans()
  4243. if err != nil {
  4244. t.Errorf("error waiting for active quota scans: %v", err)
  4245. }
  4246. user, _, err = httpd.GetUserByID(user.ID, http.StatusOK)
  4247. if err != nil {
  4248. t.Errorf("unable to get user: %v", err)
  4249. }
  4250. user.QuotaSize = user.UsedQuotaSize - 1
  4251. _, _, err = httpd.UpdateUser(user, http.StatusOK)
  4252. if err != nil {
  4253. t.Errorf("unable to update user: %v", err)
  4254. }
  4255. out, err = pushToGitRepo(clonePath)
  4256. if err == nil {
  4257. t.Errorf("git push must fail if quota is exceeded, out: %v", string(out))
  4258. }
  4259. _, err = httpd.RemoveUser(user, http.StatusOK)
  4260. if err != nil {
  4261. t.Errorf("unable to remove user: %v", err)
  4262. }
  4263. os.RemoveAll(user.GetHomeDir())
  4264. os.RemoveAll(clonePath)
  4265. }
  4266. func TestGitErrors(t *testing.T) {
  4267. if len(gitPath) == 0 || len(sshPath) == 0 {
  4268. t.Skip("git and/or ssh command not found, unable to execute this test")
  4269. }
  4270. usePubKey := true
  4271. u := getTestUser(usePubKey)
  4272. user, _, err := httpd.AddUser(u, http.StatusOK)
  4273. if err != nil {
  4274. t.Errorf("unable to add user: %v", err)
  4275. }
  4276. repoName := "testrepo"
  4277. clonePath := filepath.Join(homeBasePath, repoName)
  4278. os.RemoveAll(user.GetHomeDir())
  4279. os.RemoveAll(filepath.Join(homeBasePath, repoName))
  4280. out, err := cloneGitRepo(homeBasePath, "/"+repoName, user.Username)
  4281. if err == nil {
  4282. t.Errorf("cloning a missing repo must fail, out: %v", string(out))
  4283. }
  4284. _, err = httpd.RemoveUser(user, http.StatusOK)
  4285. if err != nil {
  4286. t.Errorf("unable to remove user: %v", err)
  4287. }
  4288. os.RemoveAll(user.GetHomeDir())
  4289. os.RemoveAll(clonePath)
  4290. }
  4291. // Start SCP tests
  4292. func TestSCPBasicHandling(t *testing.T) {
  4293. if len(scpPath) == 0 {
  4294. t.Skip("scp command not found, unable to execute this test")
  4295. }
  4296. usePubKey := true
  4297. u := getTestUser(usePubKey)
  4298. u.QuotaSize = 6553600
  4299. user, _, err := httpd.AddUser(u, http.StatusOK)
  4300. if err != nil {
  4301. t.Errorf("unable to add user: %v", err)
  4302. }
  4303. testFileName := "test_file.dat"
  4304. testFilePath := filepath.Join(homeBasePath, testFileName)
  4305. testFileSize := int64(131074)
  4306. expectedQuotaSize := user.UsedQuotaSize + testFileSize
  4307. expectedQuotaFiles := user.UsedQuotaFiles + 1
  4308. err = createTestFile(testFilePath, testFileSize)
  4309. if err != nil {
  4310. t.Errorf("unable to create test file: %v", err)
  4311. }
  4312. remoteUpPath := fmt.Sprintf("%[email protected]:%v", user.Username, "/")
  4313. remoteDownPath := fmt.Sprintf("%[email protected]:%v", user.Username, path.Join("/", testFileName))
  4314. localPath := filepath.Join(homeBasePath, "scp_download.dat")
  4315. // test to download a missing file
  4316. err = scpDownload(localPath, remoteDownPath, false, false)
  4317. if err == nil {
  4318. t.Errorf("downloading a missing file via scp must fail")
  4319. }
  4320. err = scpUpload(testFilePath, remoteUpPath, false, false)
  4321. if err != nil {
  4322. t.Errorf("error uploading file via scp: %v", err)
  4323. }
  4324. err = scpDownload(localPath, remoteDownPath, false, false)
  4325. if err != nil {
  4326. t.Errorf("error downloading file via scp: %v", err)
  4327. }
  4328. fi, err := os.Stat(localPath)
  4329. if err != nil {
  4330. t.Errorf("stat for the downloaded file must succeed")
  4331. } else {
  4332. if fi.Size() != testFileSize {
  4333. t.Errorf("size of the file downloaded via SCP does not match the expected one: %v/%v",
  4334. fi.Size(), testFileSize)
  4335. }
  4336. }
  4337. os.Remove(localPath)
  4338. user, _, err = httpd.GetUserByID(user.ID, http.StatusOK)
  4339. if err != nil {
  4340. t.Errorf("error getting user: %v", err)
  4341. }
  4342. if expectedQuotaFiles != user.UsedQuotaFiles {
  4343. t.Errorf("quota files does not match, expected: %v, actual: %v", expectedQuotaFiles, user.UsedQuotaFiles)
  4344. }
  4345. if expectedQuotaSize != user.UsedQuotaSize {
  4346. t.Errorf("quota size does not match, expected: %v, actual: %v", expectedQuotaSize, user.UsedQuotaSize)
  4347. }
  4348. err = os.RemoveAll(user.GetHomeDir())
  4349. if err != nil {
  4350. t.Errorf("error removing uploaded files")
  4351. }
  4352. _, err = httpd.RemoveUser(user, http.StatusOK)
  4353. if err != nil {
  4354. t.Errorf("unable to remove user: %v", err)
  4355. }
  4356. os.Remove(testFilePath)
  4357. }
  4358. func TestSCPUploadFileOverwrite(t *testing.T) {
  4359. if len(scpPath) == 0 {
  4360. t.Skip("scp command not found, unable to execute this test")
  4361. }
  4362. usePubKey := true
  4363. u := getTestUser(usePubKey)
  4364. u.QuotaFiles = 1000
  4365. user, _, err := httpd.AddUser(u, http.StatusOK)
  4366. if err != nil {
  4367. t.Errorf("unable to add user: %v", err)
  4368. }
  4369. os.RemoveAll(user.GetHomeDir())
  4370. testFileName := "test_file.dat"
  4371. testFilePath := filepath.Join(homeBasePath, testFileName)
  4372. testFileSize := int64(32760)
  4373. err = createTestFile(testFilePath, testFileSize)
  4374. if err != nil {
  4375. t.Errorf("unable to create test file: %v", err)
  4376. }
  4377. remoteUpPath := fmt.Sprintf("%[email protected]:%v", user.Username, path.Join("/", testFileName))
  4378. err = scpUpload(testFilePath, remoteUpPath, true, false)
  4379. if err != nil {
  4380. t.Errorf("error uploading file via scp: %v", err)
  4381. }
  4382. // test a new upload that must overwrite the existing file
  4383. err = scpUpload(testFilePath, remoteUpPath, true, false)
  4384. if err != nil {
  4385. t.Errorf("error uploading existing file via scp: %v", err)
  4386. }
  4387. user, _, err = httpd.GetUserByID(user.ID, http.StatusOK)
  4388. if err != nil {
  4389. t.Errorf("error getting user: %v", err)
  4390. }
  4391. if user.UsedQuotaSize != testFileSize || user.UsedQuotaFiles != 1 {
  4392. t.Errorf("update quota error on file overwrite, actual size: %v, expected: %v actual files: %v, expected: 1",
  4393. user.UsedQuotaSize, testFileSize, user.UsedQuotaFiles)
  4394. }
  4395. remoteDownPath := fmt.Sprintf("%[email protected]:%v", user.Username, path.Join("/", testFileName))
  4396. localPath := filepath.Join(homeBasePath, "scp_download.dat")
  4397. err = scpDownload(localPath, remoteDownPath, false, false)
  4398. if err != nil {
  4399. t.Errorf("error downloading file via scp: %v", err)
  4400. }
  4401. fi, err := os.Stat(localPath)
  4402. if err != nil {
  4403. t.Errorf("stat for the downloaded file must succeed")
  4404. } else {
  4405. if fi.Size() != testFileSize {
  4406. t.Errorf("size of the file downloaded via SCP does not match the expected one: %v/%v",
  4407. fi.Size(), testFileSize)
  4408. }
  4409. }
  4410. os.Remove(localPath)
  4411. os.Remove(testFilePath)
  4412. err = os.RemoveAll(user.GetHomeDir())
  4413. if err != nil {
  4414. t.Errorf("error removing uploaded files")
  4415. }
  4416. _, err = httpd.RemoveUser(user, http.StatusOK)
  4417. if err != nil {
  4418. t.Errorf("unable to remove user: %v", err)
  4419. }
  4420. }
  4421. func TestSCPRecursive(t *testing.T) {
  4422. if len(scpPath) == 0 {
  4423. t.Skip("scp command not found, unable to execute this test")
  4424. }
  4425. usePubKey := true
  4426. u := getTestUser(usePubKey)
  4427. user, _, err := httpd.AddUser(u, http.StatusOK)
  4428. if err != nil {
  4429. t.Errorf("unable to add user: %v", err)
  4430. }
  4431. testFileName := "test_file.dat"
  4432. testBaseDirName := "test_dir"
  4433. testBaseDirPath := filepath.Join(homeBasePath, testBaseDirName)
  4434. testBaseDirDownName := "test_dir_down"
  4435. testBaseDirDownPath := filepath.Join(homeBasePath, testBaseDirDownName)
  4436. testFilePath := filepath.Join(homeBasePath, testBaseDirName, testFileName)
  4437. testFilePath1 := filepath.Join(homeBasePath, testBaseDirName, testBaseDirName, testFileName)
  4438. testFileSize := int64(131074)
  4439. createTestFile(testFilePath, testFileSize)
  4440. createTestFile(testFilePath1, testFileSize)
  4441. remoteDownPath := fmt.Sprintf("%[email protected]:%v", user.Username, path.Join("/", testBaseDirName))
  4442. // test to download a missing dir
  4443. err = scpDownload(testBaseDirDownPath, remoteDownPath, true, true)
  4444. if err == nil {
  4445. t.Errorf("downloading a missing dir via scp must fail")
  4446. }
  4447. remoteUpPath := fmt.Sprintf("%[email protected]:%v", user.Username, "/")
  4448. err = scpUpload(testBaseDirPath, remoteUpPath, true, false)
  4449. if err != nil {
  4450. t.Errorf("error uploading dir via scp: %v", err)
  4451. }
  4452. // overwrite existing dir
  4453. err = scpUpload(testBaseDirPath, remoteUpPath, true, false)
  4454. if err != nil {
  4455. t.Errorf("error uploading dir via scp: %v", err)
  4456. }
  4457. err = scpDownload(testBaseDirDownPath, remoteDownPath, true, true)
  4458. if err != nil {
  4459. t.Errorf("error downloading dir via scp: %v", err)
  4460. }
  4461. // test download without passing -r
  4462. err = scpDownload(testBaseDirDownPath, remoteDownPath, true, false)
  4463. if err == nil {
  4464. t.Errorf("recursive download without -r must fail")
  4465. }
  4466. fi, err := os.Stat(filepath.Join(testBaseDirDownPath, testFileName))
  4467. if err != nil {
  4468. t.Errorf("error downloading file using scp recursive: %v", err)
  4469. } else {
  4470. if fi.Size() != testFileSize {
  4471. t.Errorf("size for file downloaded using recursive scp does not match, actual: %v, expected: %v", fi.Size(), testFileSize)
  4472. }
  4473. }
  4474. fi, err = os.Stat(filepath.Join(testBaseDirDownPath, testBaseDirName, testFileName))
  4475. if err != nil {
  4476. t.Errorf("error downloading file using scp recursive: %v", err)
  4477. } else {
  4478. if fi.Size() != testFileSize {
  4479. t.Errorf("size for file downloaded using recursive scp does not match, actual: %v, expected: %v", fi.Size(), testFileSize)
  4480. }
  4481. }
  4482. // upload to a non existent dir
  4483. remoteUpPath = fmt.Sprintf("%[email protected]:%v", user.Username, "/non_existent_dir")
  4484. err = scpUpload(testBaseDirPath, remoteUpPath, true, false)
  4485. if err == nil {
  4486. t.Errorf("uploading via scp to a non existent dir must fail")
  4487. }
  4488. os.RemoveAll(testBaseDirPath)
  4489. os.RemoveAll(testBaseDirDownPath)
  4490. err = os.RemoveAll(user.GetHomeDir())
  4491. if err != nil {
  4492. t.Errorf("error removing uploaded files")
  4493. }
  4494. _, err = httpd.RemoveUser(user, http.StatusOK)
  4495. if err != nil {
  4496. t.Errorf("unable to remove user: %v", err)
  4497. }
  4498. }
  4499. func TestSCPExtensionsFilter(t *testing.T) {
  4500. if len(scpPath) == 0 {
  4501. t.Skip("scp command not found, unable to execute this test")
  4502. }
  4503. usePubKey := true
  4504. u := getTestUser(usePubKey)
  4505. user, _, err := httpd.AddUser(u, http.StatusOK)
  4506. if err != nil {
  4507. t.Errorf("unable to add user: %v", err)
  4508. }
  4509. testFileSize := int64(131072)
  4510. testFileName := "test_file.dat"
  4511. testFilePath := filepath.Join(homeBasePath, testFileName)
  4512. localPath := filepath.Join(homeBasePath, "scp_download.dat")
  4513. remoteUpPath := fmt.Sprintf("%[email protected]:%v", user.Username, "/")
  4514. remoteDownPath := fmt.Sprintf("%[email protected]:%v", user.Username, path.Join("/", testFileName))
  4515. err = createTestFile(testFilePath, testFileSize)
  4516. if err != nil {
  4517. t.Errorf("unable to create test file: %v", err)
  4518. }
  4519. err = scpUpload(testFilePath, remoteUpPath, false, false)
  4520. if err != nil {
  4521. t.Errorf("error uploading file via scp: %v", err)
  4522. }
  4523. user.Filters.FileExtensions = []dataprovider.ExtensionsFilter{
  4524. {
  4525. Path: "/",
  4526. AllowedExtensions: []string{".zip"},
  4527. DeniedExtensions: []string{},
  4528. },
  4529. }
  4530. _, _, err = httpd.UpdateUser(user, http.StatusOK)
  4531. if err != nil {
  4532. t.Errorf("unable to update user: %v", err)
  4533. }
  4534. err = scpDownload(localPath, remoteDownPath, false, false)
  4535. if err == nil {
  4536. t.Errorf("scp download must fail")
  4537. }
  4538. err = scpUpload(testFilePath, remoteUpPath, false, false)
  4539. if err == nil {
  4540. t.Error("scp upload must fail")
  4541. }
  4542. _, err = httpd.RemoveUser(user, http.StatusOK)
  4543. if err != nil {
  4544. t.Errorf("unable to remove user: %v", err)
  4545. }
  4546. os.Remove(testFilePath)
  4547. os.Remove(localPath)
  4548. os.RemoveAll(user.GetHomeDir())
  4549. }
  4550. func TestSCPVirtualFolders(t *testing.T) {
  4551. if len(scpPath) == 0 {
  4552. t.Skip("scp command not found, unable to execute this test")
  4553. }
  4554. usePubKey := true
  4555. u := getTestUser(usePubKey)
  4556. mappedPath := filepath.Join(os.TempDir(), "vdir")
  4557. vdirPath := "/vdir"
  4558. u.VirtualFolders = append(u.VirtualFolders, vfs.VirtualFolder{
  4559. VirtualPath: vdirPath,
  4560. MappedPath: mappedPath,
  4561. })
  4562. os.MkdirAll(mappedPath, 0777)
  4563. user, _, err := httpd.AddUser(u, http.StatusOK)
  4564. if err != nil {
  4565. t.Errorf("unable to add user: %v", err)
  4566. }
  4567. testFileName := "test_file.dat"
  4568. testBaseDirName := "test_dir"
  4569. testBaseDirPath := filepath.Join(homeBasePath, testBaseDirName)
  4570. testBaseDirDownName := "test_dir_down"
  4571. testBaseDirDownPath := filepath.Join(homeBasePath, testBaseDirDownName)
  4572. testFilePath := filepath.Join(homeBasePath, testBaseDirName, testFileName)
  4573. testFilePath1 := filepath.Join(homeBasePath, testBaseDirName, testBaseDirName, testFileName)
  4574. testFileSize := int64(131074)
  4575. createTestFile(testFilePath, testFileSize)
  4576. createTestFile(testFilePath1, testFileSize)
  4577. remoteDownPath := fmt.Sprintf("%[email protected]:%v", user.Username, path.Join("/", vdirPath))
  4578. remoteUpPath := fmt.Sprintf("%[email protected]:%v", user.Username, vdirPath)
  4579. err = scpUpload(testBaseDirPath, remoteUpPath, true, false)
  4580. if err != nil {
  4581. t.Errorf("error uploading dir via scp: %v", err)
  4582. }
  4583. err = scpDownload(testBaseDirDownPath, remoteDownPath, true, true)
  4584. if err != nil {
  4585. t.Errorf("error downloading dir via scp: %v", err)
  4586. }
  4587. _, err = httpd.RemoveUser(user, http.StatusOK)
  4588. if err != nil {
  4589. t.Errorf("unable to remove user: %v", err)
  4590. }
  4591. os.RemoveAll(testBaseDirPath)
  4592. os.RemoveAll(testBaseDirDownPath)
  4593. os.RemoveAll(user.GetHomeDir())
  4594. os.RemoveAll(mappedPath)
  4595. }
  4596. func TestSCPPermsSubDirs(t *testing.T) {
  4597. if len(scpPath) == 0 {
  4598. t.Skip("scp command not found, unable to execute this test")
  4599. }
  4600. usePubKey := true
  4601. u := getTestUser(usePubKey)
  4602. u.Permissions["/"] = []string{dataprovider.PermAny}
  4603. u.Permissions["/somedir"] = []string{dataprovider.PermListItems, dataprovider.PermUpload}
  4604. user, _, err := httpd.AddUser(u, http.StatusOK)
  4605. if err != nil {
  4606. t.Errorf("unable to add user: %v", err)
  4607. }
  4608. localPath := filepath.Join(homeBasePath, "scp_download.dat")
  4609. subPath := filepath.Join(user.GetHomeDir(), "somedir")
  4610. testFileSize := int64(65535)
  4611. os.MkdirAll(subPath, 0777)
  4612. remoteDownPath := fmt.Sprintf("%[email protected]:%v", user.Username, "/somedir")
  4613. err = scpDownload(localPath, remoteDownPath, false, true)
  4614. if err == nil {
  4615. t.Error("download a dir with no permissions must fail")
  4616. }
  4617. os.Remove(subPath)
  4618. err = createTestFile(subPath, testFileSize)
  4619. if err != nil {
  4620. t.Errorf("unable to create test file: %v", err)
  4621. }
  4622. err = scpDownload(localPath, remoteDownPath, false, false)
  4623. if err != nil {
  4624. t.Errorf("unexpected download error: %v", err)
  4625. }
  4626. os.Chmod(subPath, 0001)
  4627. err = scpDownload(localPath, remoteDownPath, false, false)
  4628. if err == nil {
  4629. t.Error("download a file with no system permissions must fail")
  4630. }
  4631. os.Chmod(subPath, 0755)
  4632. os.Remove(localPath)
  4633. os.RemoveAll(user.GetHomeDir())
  4634. _, err = httpd.RemoveUser(user, http.StatusOK)
  4635. if err != nil {
  4636. t.Errorf("unable to remove user: %v", err)
  4637. }
  4638. }
  4639. func TestSCPPermCreateDirs(t *testing.T) {
  4640. if len(scpPath) == 0 {
  4641. t.Skip("scp command not found, unable to execute this test")
  4642. }
  4643. usePubKey := true
  4644. u := getTestUser(usePubKey)
  4645. u.Permissions["/"] = []string{dataprovider.PermDownload, dataprovider.PermUpload}
  4646. user, _, err := httpd.AddUser(u, http.StatusOK)
  4647. if err != nil {
  4648. t.Errorf("unable to add user: %v", err)
  4649. }
  4650. testFileName := "test_file.dat"
  4651. testFilePath := filepath.Join(homeBasePath, testFileName)
  4652. testFileSize := int64(32760)
  4653. testBaseDirName := "test_dir"
  4654. testBaseDirPath := filepath.Join(homeBasePath, testBaseDirName)
  4655. testFilePath1 := filepath.Join(homeBasePath, testBaseDirName, testFileName)
  4656. err = createTestFile(testFilePath, testFileSize)
  4657. if err != nil {
  4658. t.Errorf("unable to create test file: %v", err)
  4659. }
  4660. err = createTestFile(testFilePath1, testFileSize)
  4661. if err != nil {
  4662. t.Errorf("unable to create test file: %v", err)
  4663. }
  4664. remoteUpPath := fmt.Sprintf("%[email protected]:%v", user.Username, "/tmp/")
  4665. err = scpUpload(testFilePath, remoteUpPath, true, false)
  4666. if err == nil {
  4667. t.Errorf("scp upload must fail, the user cannot create files in a missing dir")
  4668. }
  4669. err = scpUpload(testBaseDirPath, remoteUpPath, true, false)
  4670. if err == nil {
  4671. t.Errorf("scp upload must fail, the user cannot create new dirs")
  4672. }
  4673. err = os.Remove(testFilePath)
  4674. if err != nil {
  4675. t.Errorf("error removing test file")
  4676. }
  4677. os.RemoveAll(testBaseDirPath)
  4678. err = os.RemoveAll(user.GetHomeDir())
  4679. if err != nil {
  4680. t.Errorf("error removing uploaded files")
  4681. }
  4682. _, err = httpd.RemoveUser(user, http.StatusOK)
  4683. if err != nil {
  4684. t.Errorf("unable to remove user: %v", err)
  4685. }
  4686. }
  4687. func TestSCPPermUpload(t *testing.T) {
  4688. if len(scpPath) == 0 {
  4689. t.Skip("scp command not found, unable to execute this test")
  4690. }
  4691. usePubKey := true
  4692. u := getTestUser(usePubKey)
  4693. u.Permissions["/"] = []string{dataprovider.PermDownload, dataprovider.PermCreateDirs}
  4694. user, _, err := httpd.AddUser(u, http.StatusOK)
  4695. if err != nil {
  4696. t.Errorf("unable to add user: %v", err)
  4697. }
  4698. testFileName := "test_file.dat"
  4699. testFilePath := filepath.Join(homeBasePath, testFileName)
  4700. testFileSize := int64(65536)
  4701. err = createTestFile(testFilePath, testFileSize)
  4702. if err != nil {
  4703. t.Errorf("unable to create test file: %v", err)
  4704. }
  4705. remoteUpPath := fmt.Sprintf("%[email protected]:%v", user.Username, "/tmp")
  4706. err = scpUpload(testFilePath, remoteUpPath, true, false)
  4707. if err == nil {
  4708. t.Errorf("scp upload must fail, the user cannot upload")
  4709. }
  4710. err = os.Remove(testFilePath)
  4711. if err != nil {
  4712. t.Errorf("error removing test file")
  4713. }
  4714. err = os.RemoveAll(user.GetHomeDir())
  4715. if err != nil {
  4716. t.Errorf("error removing uploaded files")
  4717. }
  4718. _, err = httpd.RemoveUser(user, http.StatusOK)
  4719. if err != nil {
  4720. t.Errorf("unable to remove user: %v", err)
  4721. }
  4722. }
  4723. func TestSCPPermOverwrite(t *testing.T) {
  4724. if len(scpPath) == 0 {
  4725. t.Skip("scp command not found, unable to execute this test")
  4726. }
  4727. usePubKey := true
  4728. u := getTestUser(usePubKey)
  4729. u.Permissions["/"] = []string{dataprovider.PermUpload, dataprovider.PermCreateDirs}
  4730. user, _, err := httpd.AddUser(u, http.StatusOK)
  4731. if err != nil {
  4732. t.Errorf("unable to add user: %v", err)
  4733. }
  4734. testFileName := "test_file.dat"
  4735. testFilePath := filepath.Join(homeBasePath, testFileName)
  4736. testFileSize := int64(65536)
  4737. err = createTestFile(testFilePath, testFileSize)
  4738. if err != nil {
  4739. t.Errorf("unable to create test file: %v", err)
  4740. }
  4741. remoteUpPath := fmt.Sprintf("%[email protected]:%v", user.Username, "/tmp")
  4742. err = scpUpload(testFilePath, remoteUpPath, true, false)
  4743. if err != nil {
  4744. t.Errorf("scp upload error: %v", err)
  4745. }
  4746. err = scpUpload(testFilePath, remoteUpPath, true, false)
  4747. if err == nil {
  4748. t.Errorf("scp upload must fail, the user cannot ovewrite existing files")
  4749. }
  4750. err = os.Remove(testFilePath)
  4751. if err != nil {
  4752. t.Errorf("error removing test file")
  4753. }
  4754. err = os.RemoveAll(user.GetHomeDir())
  4755. if err != nil {
  4756. t.Errorf("error removing uploaded files")
  4757. }
  4758. _, err = httpd.RemoveUser(user, http.StatusOK)
  4759. if err != nil {
  4760. t.Errorf("unable to remove user: %v", err)
  4761. }
  4762. }
  4763. func TestSCPPermDownload(t *testing.T) {
  4764. if len(scpPath) == 0 {
  4765. t.Skip("scp command not found, unable to execute this test")
  4766. }
  4767. usePubKey := true
  4768. u := getTestUser(usePubKey)
  4769. u.Permissions["/"] = []string{dataprovider.PermUpload, dataprovider.PermCreateDirs}
  4770. user, _, err := httpd.AddUser(u, http.StatusOK)
  4771. if err != nil {
  4772. t.Errorf("unable to add user: %v", err)
  4773. }
  4774. testFileName := "test_file.dat"
  4775. testFilePath := filepath.Join(homeBasePath, testFileName)
  4776. testFileSize := int64(65537)
  4777. err = createTestFile(testFilePath, testFileSize)
  4778. if err != nil {
  4779. t.Errorf("unable to create test file: %v", err)
  4780. }
  4781. remoteUpPath := fmt.Sprintf("%[email protected]:%v", user.Username, "/")
  4782. err = scpUpload(testFilePath, remoteUpPath, true, false)
  4783. if err != nil {
  4784. t.Errorf("error uploading existing file via scp: %v", err)
  4785. }
  4786. remoteDownPath := fmt.Sprintf("%[email protected]:%v", user.Username, path.Join("/", testFileName))
  4787. localPath := filepath.Join(homeBasePath, "scp_download.dat")
  4788. err = scpDownload(localPath, remoteDownPath, false, false)
  4789. if err == nil {
  4790. t.Errorf("scp download must fail, the user cannot download")
  4791. }
  4792. err = os.Remove(testFilePath)
  4793. if err != nil {
  4794. t.Errorf("error removing test file")
  4795. }
  4796. err = os.RemoveAll(user.GetHomeDir())
  4797. if err != nil {
  4798. t.Errorf("error removing uploaded files")
  4799. }
  4800. _, err = httpd.RemoveUser(user, http.StatusOK)
  4801. if err != nil {
  4802. t.Errorf("unable to remove user: %v", err)
  4803. }
  4804. }
  4805. func TestSCPQuotaSize(t *testing.T) {
  4806. if len(scpPath) == 0 {
  4807. t.Skip("scp command not found, unable to execute this test")
  4808. }
  4809. usePubKey := true
  4810. testFileSize := int64(65535)
  4811. u := getTestUser(usePubKey)
  4812. u.QuotaFiles = 1
  4813. u.QuotaSize = testFileSize - 1
  4814. user, _, err := httpd.AddUser(u, http.StatusOK)
  4815. if err != nil {
  4816. t.Errorf("unable to add user: %v", err)
  4817. }
  4818. testFileName := "test_file.dat"
  4819. testFilePath := filepath.Join(homeBasePath, testFileName)
  4820. err = createTestFile(testFilePath, testFileSize)
  4821. if err != nil {
  4822. t.Errorf("unable to create test file: %v", err)
  4823. }
  4824. remoteUpPath := fmt.Sprintf("%[email protected]:%v", user.Username, path.Join("/", testFileName))
  4825. err = scpUpload(testFilePath, remoteUpPath, true, false)
  4826. if err != nil {
  4827. t.Errorf("error uploading existing file via scp: %v", err)
  4828. }
  4829. err = scpUpload(testFilePath, remoteUpPath+".quota", true, false)
  4830. if err == nil {
  4831. t.Errorf("user is over quota scp upload must fail")
  4832. }
  4833. err = os.Remove(testFilePath)
  4834. if err != nil {
  4835. t.Errorf("error removing test file")
  4836. }
  4837. err = os.RemoveAll(user.GetHomeDir())
  4838. if err != nil {
  4839. t.Errorf("error removing uploaded files")
  4840. }
  4841. _, err = httpd.RemoveUser(user, http.StatusOK)
  4842. if err != nil {
  4843. t.Errorf("unable to remove user: %v", err)
  4844. }
  4845. }
  4846. func TestSCPEscapeHomeDir(t *testing.T) {
  4847. if len(scpPath) == 0 {
  4848. t.Skip("scp command not found, unable to execute this test")
  4849. }
  4850. usePubKey := true
  4851. user, _, err := httpd.AddUser(getTestUser(usePubKey), http.StatusOK)
  4852. if err != nil {
  4853. t.Errorf("unable to add user: %v", err)
  4854. }
  4855. os.MkdirAll(user.GetHomeDir(), 0777)
  4856. testDir := "testDir"
  4857. linkPath := filepath.Join(homeBasePath, defaultUsername, testDir)
  4858. err = os.Symlink(homeBasePath, linkPath)
  4859. if err != nil {
  4860. t.Errorf("error making local symlink: %v", err)
  4861. }
  4862. testFileName := "test_file.dat"
  4863. testFilePath := filepath.Join(homeBasePath, testFileName)
  4864. testFileSize := int64(65535)
  4865. err = createTestFile(testFilePath, testFileSize)
  4866. if err != nil {
  4867. t.Errorf("unable to create test file: %v", err)
  4868. }
  4869. remoteUpPath := fmt.Sprintf("%[email protected]:%v", user.Username, path.Join(testDir, testDir))
  4870. err = scpUpload(testFilePath, remoteUpPath, false, false)
  4871. if err == nil {
  4872. t.Errorf("uploading to a dir with a symlink outside home dir must fail")
  4873. }
  4874. remoteDownPath := fmt.Sprintf("%[email protected]:%v", user.Username, path.Join("/", testDir, testFileName))
  4875. localPath := filepath.Join(homeBasePath, "scp_download.dat")
  4876. err = scpDownload(localPath, remoteDownPath, false, false)
  4877. if err == nil {
  4878. t.Errorf("scp download must fail, the requested file has a symlink outside user home")
  4879. }
  4880. remoteDownPath = fmt.Sprintf("%[email protected]:%v", user.Username, path.Join("/", testDir))
  4881. err = scpDownload(homeBasePath, remoteDownPath, false, true)
  4882. if err == nil {
  4883. t.Errorf("scp download must fail, the requested dir is a symlink outside user home")
  4884. }
  4885. err = os.Remove(testFilePath)
  4886. if err != nil {
  4887. t.Errorf("error removing test file")
  4888. }
  4889. err = os.RemoveAll(user.GetHomeDir())
  4890. if err != nil {
  4891. t.Errorf("error removing uploaded files")
  4892. }
  4893. _, err = httpd.RemoveUser(user, http.StatusOK)
  4894. if err != nil {
  4895. t.Errorf("unable to remove user: %v", err)
  4896. }
  4897. }
  4898. func TestSCPUploadPaths(t *testing.T) {
  4899. if len(scpPath) == 0 {
  4900. t.Skip("scp command not found, unable to execute this test")
  4901. }
  4902. usePubKey := true
  4903. user, _, err := httpd.AddUser(getTestUser(usePubKey), http.StatusOK)
  4904. if err != nil {
  4905. t.Errorf("unable to add user: %v", err)
  4906. }
  4907. testFileName := "test_file.dat"
  4908. testFilePath := filepath.Join(homeBasePath, testFileName)
  4909. testFileSize := int64(65535)
  4910. testDirName := "testDir"
  4911. testDirPath := filepath.Join(user.GetHomeDir(), testDirName)
  4912. os.MkdirAll(testDirPath, 0777)
  4913. err = createTestFile(testFilePath, testFileSize)
  4914. if err != nil {
  4915. t.Errorf("unable to create test file: %v", err)
  4916. }
  4917. remoteUpPath := fmt.Sprintf("%[email protected]:%v", user.Username, testDirName)
  4918. remoteDownPath := fmt.Sprintf("%[email protected]:%v", user.Username, path.Join(testDirName, testFileName))
  4919. localPath := filepath.Join(homeBasePath, "scp_download.dat")
  4920. err = scpUpload(testFilePath, remoteUpPath, false, false)
  4921. if err != nil {
  4922. t.Errorf("scp upload error: %v", err)
  4923. }
  4924. err = scpDownload(localPath, remoteDownPath, false, false)
  4925. if err != nil {
  4926. t.Errorf("scp download error: %v", err)
  4927. }
  4928. // upload a file to a missing dir
  4929. remoteUpPath = fmt.Sprintf("%[email protected]:%v", user.Username, path.Join(testDirName, testDirName, testFileName))
  4930. err = scpUpload(testFilePath, remoteUpPath, false, false)
  4931. if err == nil {
  4932. t.Errorf("scp upload to a missing dir must fail")
  4933. }
  4934. err = os.RemoveAll(user.GetHomeDir())
  4935. if err != nil {
  4936. t.Errorf("error removing uploaded files")
  4937. }
  4938. os.Remove(localPath)
  4939. _, err = httpd.RemoveUser(user, http.StatusOK)
  4940. if err != nil {
  4941. t.Errorf("unable to remove user: %v", err)
  4942. }
  4943. }
  4944. func TestSCPOverwriteDirWithFile(t *testing.T) {
  4945. if len(scpPath) == 0 {
  4946. t.Skip("scp command not found, unable to execute this test")
  4947. }
  4948. usePubKey := true
  4949. user, _, err := httpd.AddUser(getTestUser(usePubKey), http.StatusOK)
  4950. if err != nil {
  4951. t.Errorf("unable to add user: %v", err)
  4952. }
  4953. testFileName := "test_file.dat"
  4954. testFilePath := filepath.Join(homeBasePath, testFileName)
  4955. testFileSize := int64(65535)
  4956. testDirPath := filepath.Join(user.GetHomeDir(), testFileName)
  4957. os.MkdirAll(testDirPath, 0777)
  4958. err = createTestFile(testFilePath, testFileSize)
  4959. if err != nil {
  4960. t.Errorf("unable to create test file: %v", err)
  4961. }
  4962. remoteUpPath := fmt.Sprintf("%[email protected]:%v", user.Username, "/")
  4963. err = scpUpload(testFilePath, remoteUpPath, false, false)
  4964. if err == nil {
  4965. t.Errorf("copying a file over an existing dir must fail")
  4966. }
  4967. err = os.RemoveAll(user.GetHomeDir())
  4968. if err != nil {
  4969. t.Errorf("error removing uploaded files")
  4970. }
  4971. _, err = httpd.RemoveUser(user, http.StatusOK)
  4972. if err != nil {
  4973. t.Errorf("unable to remove user: %v", err)
  4974. }
  4975. }
  4976. func TestSCPRemoteToRemote(t *testing.T) {
  4977. if len(scpPath) == 0 {
  4978. t.Skip("scp command not found, unable to execute this test")
  4979. }
  4980. usePubKey := true
  4981. user, _, err := httpd.AddUser(getTestUser(usePubKey), http.StatusOK)
  4982. if err != nil {
  4983. t.Errorf("unable to add user: %v", err)
  4984. }
  4985. u := getTestUser(usePubKey)
  4986. u.Username += "1"
  4987. u.HomeDir += "1"
  4988. user1, _, err := httpd.AddUser(u, http.StatusOK)
  4989. if err != nil {
  4990. t.Errorf("unable to add user: %v", err)
  4991. }
  4992. testFileName := "test_file.dat"
  4993. testFilePath := filepath.Join(homeBasePath, testFileName)
  4994. testFileSize := int64(65535)
  4995. err = createTestFile(testFilePath, testFileSize)
  4996. if err != nil {
  4997. t.Errorf("unable to create test file: %v", err)
  4998. }
  4999. remoteUpPath := fmt.Sprintf("%[email protected]:%v", user.Username, path.Join("/", testFileName))
  5000. remote1UpPath := fmt.Sprintf("%[email protected]:%v", user1.Username, path.Join("/", testFileName))
  5001. err = scpUpload(testFilePath, remoteUpPath, false, false)
  5002. if err != nil {
  5003. t.Errorf("scp upload error: %v", err)
  5004. }
  5005. err = scpUpload(remoteUpPath, remote1UpPath, false, true)
  5006. if err != nil {
  5007. t.Errorf("scp upload remote to remote error: %v", err)
  5008. }
  5009. err = os.RemoveAll(user.GetHomeDir())
  5010. if err != nil {
  5011. t.Errorf("error removing uploaded files")
  5012. }
  5013. _, err = httpd.RemoveUser(user, http.StatusOK)
  5014. if err != nil {
  5015. t.Errorf("unable to remove user: %v", err)
  5016. }
  5017. err = os.RemoveAll(user1.GetHomeDir())
  5018. if err != nil {
  5019. t.Errorf("error removing uploaded files for user1")
  5020. }
  5021. _, err = httpd.RemoveUser(user1, http.StatusOK)
  5022. if err != nil {
  5023. t.Errorf("unable to remove user1: %v", err)
  5024. }
  5025. }
  5026. func TestSCPErrors(t *testing.T) {
  5027. if len(scpPath) == 0 {
  5028. t.Skip("scp command not found, unable to execute this test")
  5029. }
  5030. u := getTestUser(true)
  5031. user, _, err := httpd.AddUser(u, http.StatusOK)
  5032. if err != nil {
  5033. t.Errorf("unable to add user: %v", err)
  5034. }
  5035. testFileSize := int64(524288)
  5036. testFileName := "test_file.dat"
  5037. testFilePath := filepath.Join(homeBasePath, testFileName)
  5038. err = createTestFile(testFilePath, testFileSize)
  5039. if err != nil {
  5040. t.Errorf("unable to create test file: %v", err)
  5041. }
  5042. remoteUpPath := fmt.Sprintf("%[email protected]:%v", user.Username, "/")
  5043. remoteDownPath := fmt.Sprintf("%[email protected]:%v", user.Username, path.Join("/", testFileName))
  5044. localPath := filepath.Join(homeBasePath, "scp_download.dat")
  5045. err = scpUpload(testFilePath, remoteUpPath, false, false)
  5046. if err != nil {
  5047. t.Errorf("error uploading file via scp: %v", err)
  5048. }
  5049. user.UploadBandwidth = 512
  5050. user.DownloadBandwidth = 512
  5051. _, _, err = httpd.UpdateUser(user, http.StatusOK)
  5052. if err != nil {
  5053. t.Errorf("unable to update user: %v", err)
  5054. }
  5055. cmd := getScpDownloadCommand(localPath, remoteDownPath, false, false)
  5056. go func() {
  5057. if cmd.Run() == nil {
  5058. t.Errorf("SCP download must fail")
  5059. }
  5060. }()
  5061. waitForActiveTransfer()
  5062. // wait some additional arbitrary time to wait for transfer activity to happen
  5063. // it is need to reach all the code in CheckIdleConnections
  5064. time.Sleep(100 * time.Millisecond)
  5065. cmd.Process.Kill()
  5066. waitForNoActiveTransfer()
  5067. cmd = getScpUploadCommand(testFilePath, remoteUpPath, false, false)
  5068. go func() {
  5069. if cmd.Run() == nil {
  5070. t.Errorf("SCP upload must fail")
  5071. }
  5072. }()
  5073. waitForActiveTransfer()
  5074. // wait some additional arbitrary time to wait for transfer activity to happen
  5075. // it is need to reach all the code in CheckIdleConnections
  5076. time.Sleep(100 * time.Millisecond)
  5077. cmd.Process.Kill()
  5078. waitForNoActiveTransfer()
  5079. err = os.Remove(testFilePath)
  5080. if err != nil {
  5081. t.Errorf("error removing test file")
  5082. }
  5083. os.Remove(localPath)
  5084. err = os.RemoveAll(user.GetHomeDir())
  5085. if err != nil {
  5086. t.Errorf("error removing uploaded files")
  5087. }
  5088. _, err = httpd.RemoveUser(user, http.StatusOK)
  5089. if err != nil {
  5090. t.Errorf("unable to remove user: %v", err)
  5091. }
  5092. }
  5093. // End SCP tests
  5094. func waitTCPListening(address string) {
  5095. for {
  5096. conn, err := net.Dial("tcp", address)
  5097. if err != nil {
  5098. logger.WarnToConsole("tcp server %v not listening: %v\n", address, err)
  5099. time.Sleep(100 * time.Millisecond)
  5100. continue
  5101. }
  5102. logger.InfoToConsole("tcp server %v now listening\n", address)
  5103. defer conn.Close()
  5104. break
  5105. }
  5106. }
  5107. func getTestUser(usePubKey bool) dataprovider.User {
  5108. user := dataprovider.User{
  5109. Username: defaultUsername,
  5110. Password: defaultPassword,
  5111. HomeDir: filepath.Join(homeBasePath, defaultUsername),
  5112. Status: 1,
  5113. ExpirationDate: 0,
  5114. }
  5115. user.Permissions = make(map[string][]string)
  5116. user.Permissions["/"] = allPerms
  5117. if usePubKey {
  5118. user.PublicKeys = []string{testPubKey}
  5119. user.Password = ""
  5120. }
  5121. return user
  5122. }
  5123. func runSSHCommand(command string, user dataprovider.User, usePubKey bool) ([]byte, error) {
  5124. var sshSession *ssh.Session
  5125. var output []byte
  5126. config := &ssh.ClientConfig{
  5127. User: defaultUsername,
  5128. HostKeyCallback: func(hostname string, remote net.Addr, key ssh.PublicKey) error {
  5129. return nil
  5130. },
  5131. }
  5132. if usePubKey {
  5133. key, err := ssh.ParsePrivateKey([]byte(testPrivateKey))
  5134. if err != nil {
  5135. return output, err
  5136. }
  5137. config.Auth = []ssh.AuthMethod{ssh.PublicKeys(key)}
  5138. } else {
  5139. config.Auth = []ssh.AuthMethod{ssh.Password(defaultPassword)}
  5140. }
  5141. conn, err := ssh.Dial("tcp", sftpServerAddr, config)
  5142. if err != nil {
  5143. return output, err
  5144. }
  5145. defer conn.Close()
  5146. sshSession, err = conn.NewSession()
  5147. if err != nil {
  5148. return output, err
  5149. }
  5150. var stdout, stderr bytes.Buffer
  5151. sshSession.Stdout = &stdout
  5152. sshSession.Stderr = &stderr
  5153. err = sshSession.Run(command)
  5154. if err != nil {
  5155. return nil, fmt.Errorf("failed to run command %v: %v", command, stderr.Bytes())
  5156. }
  5157. return stdout.Bytes(), err
  5158. }
  5159. func getSftpClientWithAddr(user dataprovider.User, usePubKey bool, addr string) (*sftp.Client, error) {
  5160. var sftpClient *sftp.Client
  5161. config := &ssh.ClientConfig{
  5162. User: user.Username,
  5163. HostKeyCallback: func(hostname string, remote net.Addr, key ssh.PublicKey) error {
  5164. return nil
  5165. },
  5166. }
  5167. if usePubKey {
  5168. key, err := ssh.ParsePrivateKey([]byte(testPrivateKey))
  5169. if err != nil {
  5170. return nil, err
  5171. }
  5172. config.Auth = []ssh.AuthMethod{ssh.PublicKeys(key)}
  5173. } else {
  5174. if len(user.Password) > 0 {
  5175. config.Auth = []ssh.AuthMethod{ssh.Password(user.Password)}
  5176. } else {
  5177. config.Auth = []ssh.AuthMethod{ssh.Password(defaultPassword)}
  5178. }
  5179. }
  5180. conn, err := ssh.Dial("tcp", addr, config)
  5181. if err != nil {
  5182. return sftpClient, err
  5183. }
  5184. sftpClient, err = sftp.NewClient(conn)
  5185. return sftpClient, err
  5186. }
  5187. func getSftpClient(user dataprovider.User, usePubKey bool) (*sftp.Client, error) {
  5188. return getSftpClientWithAddr(user, usePubKey, sftpServerAddr)
  5189. }
  5190. func getKeyboardInteractiveSftpClient(user dataprovider.User, answers []string) (*sftp.Client, error) {
  5191. var sftpClient *sftp.Client
  5192. config := &ssh.ClientConfig{
  5193. User: user.Username,
  5194. HostKeyCallback: func(hostname string, remote net.Addr, key ssh.PublicKey) error {
  5195. return nil
  5196. },
  5197. Auth: []ssh.AuthMethod{
  5198. ssh.KeyboardInteractive(func(user, instruction string, questions []string, echos []bool) ([]string, error) {
  5199. return answers, nil
  5200. }),
  5201. },
  5202. }
  5203. conn, err := ssh.Dial("tcp", sftpServerAddr, config)
  5204. if err != nil {
  5205. return sftpClient, err
  5206. }
  5207. sftpClient, err = sftp.NewClient(conn)
  5208. return sftpClient, err
  5209. }
  5210. func getCustomAuthSftpClient(user dataprovider.User, authMethods []ssh.AuthMethod) (*sftp.Client, error) {
  5211. var sftpClient *sftp.Client
  5212. config := &ssh.ClientConfig{
  5213. User: user.Username,
  5214. HostKeyCallback: func(hostname string, remote net.Addr, key ssh.PublicKey) error {
  5215. return nil
  5216. },
  5217. Auth: authMethods,
  5218. }
  5219. conn, err := ssh.Dial("tcp", sftpServerAddr, config)
  5220. if err != nil {
  5221. return sftpClient, err
  5222. }
  5223. sftpClient, err = sftp.NewClient(conn)
  5224. return sftpClient, err
  5225. }
  5226. func createTestFile(path string, size int64) error {
  5227. baseDir := filepath.Dir(path)
  5228. if _, err := os.Stat(baseDir); os.IsNotExist(err) {
  5229. os.MkdirAll(baseDir, 0777)
  5230. }
  5231. content := make([]byte, size)
  5232. _, err := rand.Read(content)
  5233. if err != nil {
  5234. return err
  5235. }
  5236. return ioutil.WriteFile(path, content, 0666)
  5237. }
  5238. func appendToTestFile(path string, size int64) error {
  5239. content := make([]byte, size)
  5240. _, err := rand.Read(content)
  5241. if err != nil {
  5242. return err
  5243. }
  5244. f, err := os.OpenFile(path, os.O_APPEND|os.O_WRONLY, 0666)
  5245. if err != nil {
  5246. return err
  5247. }
  5248. written, err := io.Copy(f, bytes.NewReader(content))
  5249. if err != nil {
  5250. return err
  5251. }
  5252. if int64(written) != size {
  5253. return fmt.Errorf("write error, written: %v/%v", written, size)
  5254. }
  5255. return nil
  5256. }
  5257. func sftpUploadFile(localSourcePath string, remoteDestPath string, expectedSize int64, client *sftp.Client) error {
  5258. srcFile, err := os.Open(localSourcePath)
  5259. if err != nil {
  5260. return err
  5261. }
  5262. defer srcFile.Close()
  5263. destFile, err := client.Create(remoteDestPath)
  5264. if err != nil {
  5265. return err
  5266. }
  5267. _, err = io.Copy(destFile, srcFile)
  5268. if err != nil {
  5269. destFile.Close()
  5270. return err
  5271. }
  5272. // we need to close the file to trigger the close method on server
  5273. // we cannot defer closing or Lstat will fail for uploads in atomic mode
  5274. destFile.Close()
  5275. if expectedSize > 0 {
  5276. fi, err := client.Stat(remoteDestPath)
  5277. if err != nil {
  5278. return err
  5279. }
  5280. if fi.Size() != expectedSize {
  5281. return fmt.Errorf("uploaded file size does not match, actual: %v, expected: %v", fi.Size(), expectedSize)
  5282. }
  5283. }
  5284. return err
  5285. }
  5286. func sftpUploadResumeFile(localSourcePath string, remoteDestPath string, expectedSize int64, invalidOffset bool,
  5287. client *sftp.Client) error {
  5288. srcFile, err := os.Open(localSourcePath)
  5289. if err != nil {
  5290. return err
  5291. }
  5292. defer srcFile.Close()
  5293. fi, err := client.Lstat(remoteDestPath)
  5294. if err != nil {
  5295. return err
  5296. }
  5297. if !invalidOffset {
  5298. _, err = srcFile.Seek(fi.Size(), 0)
  5299. if err != nil {
  5300. return err
  5301. }
  5302. }
  5303. destFile, err := client.OpenFile(remoteDestPath, os.O_WRONLY|os.O_APPEND)
  5304. if err != nil {
  5305. return err
  5306. }
  5307. if !invalidOffset {
  5308. _, err = destFile.Seek(fi.Size(), 0)
  5309. if err != nil {
  5310. return err
  5311. }
  5312. }
  5313. _, err = io.Copy(destFile, srcFile)
  5314. if err != nil {
  5315. destFile.Close()
  5316. return err
  5317. }
  5318. // we need to close the file to trigger the close method on server
  5319. // we cannot defer closing or Lstat will fail for upload atomic mode
  5320. destFile.Close()
  5321. if expectedSize > 0 {
  5322. fi, err := client.Lstat(remoteDestPath)
  5323. if err != nil {
  5324. return err
  5325. }
  5326. if fi.Size() != expectedSize {
  5327. return fmt.Errorf("uploaded file size does not match, actual: %v, expected: %v", fi.Size(), expectedSize)
  5328. }
  5329. }
  5330. return err
  5331. }
  5332. func sftpDownloadFile(remoteSourcePath string, localDestPath string, expectedSize int64, client *sftp.Client) error {
  5333. downloadDest, err := os.Create(localDestPath)
  5334. if err != nil {
  5335. return err
  5336. }
  5337. defer downloadDest.Close()
  5338. sftpSrcFile, err := client.Open(remoteSourcePath)
  5339. if err != nil {
  5340. return err
  5341. }
  5342. defer sftpSrcFile.Close()
  5343. _, err = io.Copy(downloadDest, sftpSrcFile)
  5344. if err != nil {
  5345. return err
  5346. }
  5347. err = downloadDest.Sync()
  5348. if err != nil {
  5349. return err
  5350. }
  5351. if expectedSize > 0 {
  5352. fi, err := downloadDest.Stat()
  5353. if err != nil {
  5354. return err
  5355. }
  5356. if fi.Size() != expectedSize {
  5357. return fmt.Errorf("downloaded file size does not match, actual: %v, expected: %v", fi.Size(), expectedSize)
  5358. }
  5359. }
  5360. return err
  5361. }
  5362. func sftpUploadNonBlocking(localSourcePath string, remoteDestPath string, expectedSize int64, client *sftp.Client) <-chan error {
  5363. c := make(chan error)
  5364. go func() {
  5365. c <- sftpUploadFile(localSourcePath, remoteDestPath, expectedSize, client)
  5366. }()
  5367. return c
  5368. }
  5369. func sftpDownloadNonBlocking(remoteSourcePath string, localDestPath string, expectedSize int64, client *sftp.Client) <-chan error {
  5370. c := make(chan error)
  5371. go func() {
  5372. c <- sftpDownloadFile(remoteSourcePath, localDestPath, expectedSize, client)
  5373. }()
  5374. return c
  5375. }
  5376. func scpUpload(localPath, remotePath string, preserveTime, remoteToRemote bool) error {
  5377. cmd := getScpUploadCommand(localPath, remotePath, preserveTime, remoteToRemote)
  5378. return cmd.Run()
  5379. }
  5380. func scpDownload(localPath, remotePath string, preserveTime, recursive bool) error {
  5381. cmd := getScpDownloadCommand(localPath, remotePath, preserveTime, recursive)
  5382. return cmd.Run()
  5383. }
  5384. func getScpDownloadCommand(localPath, remotePath string, preserveTime, recursive bool) *exec.Cmd {
  5385. var args []string
  5386. if preserveTime {
  5387. args = append(args, "-p")
  5388. }
  5389. if recursive {
  5390. args = append(args, "-r")
  5391. }
  5392. args = append(args, "-P")
  5393. args = append(args, "2022")
  5394. args = append(args, "-o")
  5395. args = append(args, "StrictHostKeyChecking=no")
  5396. args = append(args, "-i")
  5397. args = append(args, privateKeyPath)
  5398. args = append(args, remotePath)
  5399. args = append(args, localPath)
  5400. return exec.Command(scpPath, args...)
  5401. }
  5402. func getScpUploadCommand(localPath, remotePath string, preserveTime, remoteToRemote bool) *exec.Cmd {
  5403. var args []string
  5404. if remoteToRemote {
  5405. args = append(args, "-3")
  5406. }
  5407. if preserveTime {
  5408. args = append(args, "-p")
  5409. }
  5410. fi, err := os.Stat(localPath)
  5411. if err == nil {
  5412. if fi.IsDir() {
  5413. args = append(args, "-r")
  5414. }
  5415. }
  5416. args = append(args, "-P")
  5417. args = append(args, "2022")
  5418. args = append(args, "-o")
  5419. args = append(args, "StrictHostKeyChecking=no")
  5420. args = append(args, "-i")
  5421. args = append(args, privateKeyPath)
  5422. args = append(args, localPath)
  5423. args = append(args, remotePath)
  5424. return exec.Command(scpPath, args...)
  5425. }
  5426. func computeHashForFile(hasher hash.Hash, path string) (string, error) {
  5427. hash := ""
  5428. f, err := os.Open(path)
  5429. if err != nil {
  5430. return hash, err
  5431. }
  5432. defer f.Close()
  5433. _, err = io.Copy(hasher, f)
  5434. if err == nil {
  5435. hash = fmt.Sprintf("%x", hasher.Sum(nil))
  5436. }
  5437. return hash, err
  5438. }
  5439. func waitForNoActiveTransfer() {
  5440. for len(sftpd.GetConnectionsStats()) > 0 {
  5441. time.Sleep(100 * time.Millisecond)
  5442. }
  5443. }
  5444. func waitForActiveTransfer() {
  5445. stats := sftpd.GetConnectionsStats()
  5446. for len(stats) < 1 {
  5447. stats = sftpd.GetConnectionsStats()
  5448. }
  5449. activeTransferFound := false
  5450. for !activeTransferFound {
  5451. stats = sftpd.GetConnectionsStats()
  5452. if len(stats) == 0 {
  5453. break
  5454. }
  5455. for _, stat := range stats {
  5456. if len(stat.Transfers) > 0 {
  5457. activeTransferFound = true
  5458. }
  5459. }
  5460. }
  5461. }
  5462. func waitQuotaScans() error {
  5463. time.Sleep(100 * time.Millisecond)
  5464. scans, _, err := httpd.GetQuotaScans(http.StatusOK)
  5465. if err != nil {
  5466. return err
  5467. }
  5468. for len(scans) > 0 {
  5469. time.Sleep(100 * time.Millisecond)
  5470. scans, _, err = httpd.GetQuotaScans(http.StatusOK)
  5471. if err != nil {
  5472. return err
  5473. }
  5474. }
  5475. return nil
  5476. }
  5477. func initGitRepo(path string) ([]byte, error) {
  5478. os.MkdirAll(path, 0777)
  5479. args := []string{"init", "--bare"}
  5480. cmd := exec.Command(gitPath, args...)
  5481. cmd.Dir = path
  5482. return cmd.CombinedOutput()
  5483. }
  5484. func pushToGitRepo(repoPath string) ([]byte, error) {
  5485. cmd := exec.Command(gitPath, "push")
  5486. cmd.Dir = repoPath
  5487. cmd.Env = append(os.Environ(),
  5488. fmt.Sprintf("GIT_SSH=%v", gitWrapPath))
  5489. return cmd.CombinedOutput()
  5490. }
  5491. func cloneGitRepo(basePath, remotePath, username string) ([]byte, error) {
  5492. remoteUrl := fmt.Sprintf("ssh://%[email protected]:2022%v", username, remotePath)
  5493. args := []string{"clone", remoteUrl}
  5494. cmd := exec.Command(gitPath, args...)
  5495. cmd.Dir = basePath
  5496. cmd.Env = append(os.Environ(),
  5497. fmt.Sprintf("GIT_SSH=%v", gitWrapPath))
  5498. return cmd.CombinedOutput()
  5499. }
  5500. func addFileToGitRepo(repoPath string, fileSize int64) ([]byte, error) {
  5501. path := filepath.Join(repoPath, "test")
  5502. err := createTestFile(path, fileSize)
  5503. if err != nil {
  5504. return []byte(""), err
  5505. }
  5506. cmd := exec.Command(gitPath, "config", "user.email", "[email protected]")
  5507. cmd.Dir = repoPath
  5508. out, err := cmd.CombinedOutput()
  5509. if err != nil {
  5510. return out, err
  5511. }
  5512. cmd = exec.Command(gitPath, "config", "user.name", "testuser")
  5513. cmd.Dir = repoPath
  5514. out, err = cmd.CombinedOutput()
  5515. if err != nil {
  5516. return out, err
  5517. }
  5518. cmd = exec.Command(gitPath, "add", "test")
  5519. cmd.Dir = repoPath
  5520. out, err = cmd.CombinedOutput()
  5521. if err != nil {
  5522. return out, err
  5523. }
  5524. cmd = exec.Command(gitPath, "commit", "-am", "test")
  5525. cmd.Dir = repoPath
  5526. return cmd.CombinedOutput()
  5527. }
  5528. func getKeyboardInteractiveScriptContent(questions []string, sleepTime int, nonJsonResponse bool, result int) []byte {
  5529. content := []byte("#!/bin/sh\n\n")
  5530. q, _ := json.Marshal(questions)
  5531. echos := []bool{}
  5532. for index := range questions {
  5533. echos = append(echos, index%2 == 0)
  5534. }
  5535. e, _ := json.Marshal(echos)
  5536. if nonJsonResponse {
  5537. content = append(content, []byte(fmt.Sprintf("echo 'questions: %v echos: %v\n", string(q), string(e)))...)
  5538. } else {
  5539. content = append(content, []byte(fmt.Sprintf("echo '{\"questions\":%v,\"echos\":%v}'\n", string(q), string(e)))...)
  5540. }
  5541. for index := range questions {
  5542. content = append(content, []byte(fmt.Sprintf("read ANSWER%v\n", index))...)
  5543. }
  5544. if sleepTime > 0 {
  5545. content = append(content, []byte(fmt.Sprintf("sleep %v\n", sleepTime))...)
  5546. }
  5547. content = append(content, []byte(fmt.Sprintf("echo '{\"auth_result\":%v}'\n", result))...)
  5548. return content
  5549. }
  5550. func getExtAuthScriptContent(user dataprovider.User, sleepTime int, nonJsonResponse bool) []byte {
  5551. extAuthContent := []byte("#!/bin/sh\n\n")
  5552. u, _ := json.Marshal(user)
  5553. extAuthContent = append(extAuthContent, []byte(fmt.Sprintf("if test \"$SFTPGO_AUTHD_USERNAME\" = \"%v\"; then\n", user.Username))...)
  5554. if nonJsonResponse {
  5555. extAuthContent = append(extAuthContent, []byte("echo 'text response'\n")...)
  5556. } else {
  5557. extAuthContent = append(extAuthContent, []byte(fmt.Sprintf("echo '%v'\n", string(u)))...)
  5558. }
  5559. extAuthContent = append(extAuthContent, []byte("else\n")...)
  5560. if nonJsonResponse {
  5561. extAuthContent = append(extAuthContent, []byte("echo 'text response'\n")...)
  5562. } else {
  5563. extAuthContent = append(extAuthContent, []byte("echo '{\"username\":\"\"}'\n")...)
  5564. }
  5565. extAuthContent = append(extAuthContent, []byte("fi\n")...)
  5566. if sleepTime > 0 {
  5567. extAuthContent = append(extAuthContent, []byte(fmt.Sprintf("sleep %v\n", sleepTime))...)
  5568. }
  5569. return extAuthContent
  5570. }
  5571. func getPreLoginScriptContent(user dataprovider.User, nonJsonResponse bool) []byte {
  5572. content := []byte("#!/bin/sh\n\n")
  5573. if nonJsonResponse {
  5574. content = append(content, []byte("echo 'text response'\n")...)
  5575. return content
  5576. }
  5577. if len(user.Username) > 0 {
  5578. u, _ := json.Marshal(user)
  5579. content = append(content, []byte(fmt.Sprintf("echo '%v'\n", string(u)))...)
  5580. }
  5581. return content
  5582. }
  5583. func printLatestLogs(maxNumberOfLines int) {
  5584. var lines []string
  5585. f, err := os.Open(logFilePath)
  5586. if err != nil {
  5587. return
  5588. }
  5589. defer f.Close()
  5590. scanner := bufio.NewScanner(f)
  5591. for scanner.Scan() {
  5592. lines = append(lines, scanner.Text()+"\r\n")
  5593. for len(lines) > maxNumberOfLines {
  5594. lines = lines[1:]
  5595. }
  5596. }
  5597. if scanner.Err() != nil {
  5598. logger.WarnToConsole("Unable to print latest logs: %v", scanner.Err())
  5599. return
  5600. }
  5601. for _, line := range lines {
  5602. logger.DebugToConsole(line)
  5603. }
  5604. }