sftpd_test.go 127 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795279627972798279928002801280228032804280528062807280828092810281128122813281428152816281728182819282028212822282328242825282628272828282928302831283228332834283528362837283828392840284128422843284428452846284728482849285028512852285328542855285628572858285928602861286228632864286528662867286828692870287128722873287428752876287728782879288028812882288328842885288628872888288928902891289228932894289528962897289828992900290129022903290429052906290729082909291029112912291329142915291629172918291929202921292229232924292529262927292829292930293129322933293429352936293729382939294029412942294329442945294629472948294929502951295229532954295529562957295829592960296129622963296429652966296729682969297029712972297329742975297629772978297929802981298229832984298529862987298829892990299129922993299429952996299729982999300030013002300330043005300630073008300930103011301230133014301530163017301830193020302130223023302430253026302730283029303030313032303330343035303630373038303930403041304230433044304530463047304830493050305130523053305430553056305730583059306030613062306330643065306630673068306930703071307230733074307530763077307830793080308130823083308430853086308730883089309030913092309330943095309630973098309931003101310231033104310531063107310831093110311131123113311431153116311731183119312031213122312331243125312631273128312931303131313231333134313531363137313831393140314131423143314431453146314731483149315031513152315331543155315631573158315931603161316231633164316531663167316831693170317131723173317431753176317731783179318031813182318331843185318631873188318931903191319231933194319531963197319831993200320132023203320432053206320732083209321032113212321332143215321632173218321932203221322232233224322532263227322832293230323132323233323432353236323732383239324032413242324332443245324632473248324932503251325232533254325532563257325832593260326132623263326432653266326732683269327032713272327332743275327632773278327932803281328232833284328532863287328832893290329132923293329432953296329732983299330033013302330333043305330633073308330933103311331233133314331533163317331833193320332133223323332433253326332733283329333033313332333333343335333633373338333933403341334233433344334533463347334833493350335133523353335433553356335733583359336033613362336333643365336633673368336933703371337233733374337533763377337833793380338133823383338433853386338733883389339033913392339333943395339633973398339934003401340234033404340534063407340834093410341134123413341434153416341734183419342034213422342334243425342634273428342934303431343234333434343534363437343834393440344134423443344434453446344734483449345034513452345334543455345634573458345934603461346234633464346534663467346834693470347134723473347434753476347734783479348034813482348334843485348634873488348934903491349234933494349534963497349834993500350135023503350435053506350735083509351035113512351335143515351635173518351935203521352235233524352535263527352835293530353135323533353435353536353735383539354035413542354335443545354635473548354935503551355235533554355535563557355835593560356135623563356435653566356735683569357035713572357335743575357635773578357935803581358235833584358535863587358835893590359135923593359435953596359735983599360036013602360336043605360636073608360936103611361236133614361536163617361836193620362136223623362436253626362736283629363036313632363336343635363636373638363936403641364236433644364536463647364836493650365136523653365436553656365736583659366036613662366336643665366636673668366936703671367236733674367536763677367836793680368136823683368436853686368736883689369036913692369336943695369636973698369937003701370237033704370537063707370837093710371137123713371437153716371737183719372037213722372337243725372637273728372937303731373237333734373537363737373837393740374137423743374437453746374737483749375037513752375337543755375637573758375937603761376237633764376537663767376837693770377137723773377437753776377737783779378037813782378337843785378637873788378937903791379237933794379537963797379837993800380138023803380438053806380738083809381038113812381338143815381638173818381938203821382238233824382538263827382838293830383138323833383438353836383738383839384038413842384338443845384638473848384938503851385238533854385538563857385838593860386138623863386438653866386738683869387038713872387338743875387638773878387938803881388238833884388538863887388838893890389138923893389438953896389738983899390039013902390339043905390639073908390939103911391239133914391539163917391839193920392139223923392439253926392739283929393039313932393339343935393639373938393939403941394239433944394539463947394839493950395139523953395439553956395739583959396039613962396339643965396639673968396939703971397239733974397539763977397839793980398139823983398439853986398739883989399039913992399339943995399639973998399940004001400240034004400540064007400840094010401140124013401440154016401740184019402040214022402340244025402640274028402940304031403240334034403540364037403840394040404140424043404440454046404740484049405040514052405340544055
  1. package sftpd_test
  2. import (
  3. "bufio"
  4. "bytes"
  5. "crypto/rand"
  6. "crypto/sha256"
  7. "crypto/sha512"
  8. "fmt"
  9. "hash"
  10. "io"
  11. "io/ioutil"
  12. "math"
  13. "net"
  14. "net/http"
  15. "os"
  16. "os/exec"
  17. "path"
  18. "path/filepath"
  19. "runtime"
  20. "strings"
  21. "testing"
  22. "time"
  23. _ "github.com/go-sql-driver/mysql"
  24. _ "github.com/lib/pq"
  25. _ "github.com/mattn/go-sqlite3"
  26. "golang.org/x/crypto/ssh"
  27. "github.com/drakkan/sftpgo/config"
  28. "github.com/drakkan/sftpgo/dataprovider"
  29. "github.com/drakkan/sftpgo/httpd"
  30. "github.com/drakkan/sftpgo/logger"
  31. "github.com/drakkan/sftpgo/sftpd"
  32. "github.com/drakkan/sftpgo/utils"
  33. "github.com/pkg/sftp"
  34. "github.com/rs/zerolog"
  35. )
  36. const (
  37. logSender = "sftpdTesting"
  38. sftpServerAddr = "127.0.0.1:2022"
  39. defaultUsername = "test_user_sftp"
  40. defaultPassword = "test_password"
  41. testPubKey = "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQC03jj0D+djk7pxIf/0OhrxrchJTRZklofJ1NoIu4752Sq02mdXmarMVsqJ1cAjV5LBVy3D1F5U6XW4rppkXeVtd04Pxb09ehtH0pRRPaoHHlALiJt8CoMpbKYMA8b3KXPPriGxgGomvtU2T2RMURSwOZbMtpsugfjYSWenyYX+VORYhylWnSXL961LTyC21ehd6d6QnW9G7E5hYMITMY9TuQZz3bROYzXiTsgN0+g6Hn7exFQp50p45StUMfV/SftCMdCxlxuyGny2CrN/vfjO7xxOo2uv7q1qm10Q46KPWJQv+pgZ/OfL+EDjy07n5QVSKHlbx+2nT4Q0EgOSQaCTYwn3YjtABfIxWwgAFdyj6YlPulCL22qU4MYhDcA6PSBwDdf8hvxBfvsiHdM+JcSHvv8/VeJhk6CmnZxGY0fxBupov27z3yEO8nAg8k+6PaUiW1MSUfuGMF/ktB8LOstXsEPXSszuyXiOv4DaryOXUiSn7bmRqKcEFlJusO6aZP0= nicola@p1"
  42. testPubKey1 = "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQCd60+/j+y8f0tLftihWV1YN9RSahMI9btQMDIMqts/jeNbD8jgoogM3nhF7KxfcaMKURuD47KC4Ey6iAJUJ0sWkSNNxOcIYuvA+5MlspfZDsa8Ag76Fe1vyz72WeHMHMeh/hwFo2TeIeIXg480T1VI6mzfDrVp2GzUx0SS0dMsQBjftXkuVR8YOiOwMCAH2a//M1OrvV7d/NBk6kBN0WnuIBb2jKm15PAA7+jQQG7tzwk2HedNH3jeL5GH31xkSRwlBczRK0xsCQXehAlx6cT/e/s44iJcJTHfpPKoSk6UAhPJYe7Z1QnuoawY9P9jQaxpyeImBZxxUEowhjpj2avBxKdRGBVK8R7EL8tSOeLbhdyWe5Mwc1+foEbq9Zz5j5Kd+hn3Wm1UnsGCrXUUUoZp1jnlNl0NakCto+5KmqnT9cHxaY+ix2RLUWAZyVFlRq71OYux1UHJnEJPiEI1/tr4jFBSL46qhQZv/TfpkfVW8FLz0lErfqu0gQEZnNHr3Fc= nicola@p1"
  43. testPrivateKey = `-----BEGIN OPENSSH PRIVATE KEY-----
  44. b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAABlwAAAAdzc2gtcn
  45. NhAAAAAwEAAQAAAYEAtN449A/nY5O6cSH/9Doa8a3ISU0WZJaHydTaCLuO+dkqtNpnV5mq
  46. zFbKidXAI1eSwVctw9ReVOl1uK6aZF3lbXdOD8W9PXobR9KUUT2qBx5QC4ibfAqDKWymDA
  47. PG9ylzz64hsYBqJr7VNk9kTFEUsDmWzLabLoH42Elnp8mF/lTkWIcpVp0ly/etS08gttXo
  48. XenekJ1vRuxOYWDCEzGPU7kGc920TmM14k7IDdPoOh5+3sRUKedKeOUrVDH1f0n7QjHQsZ
  49. cbshp8tgqzf734zu8cTqNrr+6taptdEOOij1iUL/qYGfzny/hA48tO5+UFUih5W8ftp0+E
  50. NBIDkkGgk2MJ92I7QAXyMVsIABXco+mJT7pQi9tqlODGIQ3AOj0gcA3X/Ib8QX77Ih3TPi
  51. XEh77/P1XiYZOgpp2cRmNH8QbqaL9u898hDvJwIPJPuj2lIltTElH7hjBf5LQfCzrLV7BD
  52. 10rM7sl4jr+A2q8jl1Ikp+25kainBBZSbrDummT9AAAFgDU/VLk1P1S5AAAAB3NzaC1yc2
  53. EAAAGBALTeOPQP52OTunEh//Q6GvGtyElNFmSWh8nU2gi7jvnZKrTaZ1eZqsxWyonVwCNX
  54. ksFXLcPUXlTpdbiummRd5W13Tg/FvT16G0fSlFE9qgceUAuIm3wKgylspgwDxvcpc8+uIb
  55. GAaia+1TZPZExRFLA5lsy2my6B+NhJZ6fJhf5U5FiHKVadJcv3rUtPILbV6F3p3pCdb0bs
  56. TmFgwhMxj1O5BnPdtE5jNeJOyA3T6Doeft7EVCnnSnjlK1Qx9X9J+0Ix0LGXG7IafLYKs3
  57. +9+M7vHE6ja6/urWqbXRDjoo9YlC/6mBn858v4QOPLTuflBVIoeVvH7adPhDQSA5JBoJNj
  58. CfdiO0AF8jFbCAAV3KPpiU+6UIvbapTgxiENwDo9IHAN1/yG/EF++yId0z4lxIe+/z9V4m
  59. GToKadnEZjR/EG6mi/bvPfIQ7ycCDyT7o9pSJbUxJR+4YwX+S0Hws6y1ewQ9dKzO7JeI6/
  60. gNqvI5dSJKftuZGopwQWUm6w7ppk/QAAAAMBAAEAAAGAHKnC+Nq0XtGAkIFE4N18e6SAwy
  61. 0WSWaZqmCzFQM0S2AhJnweOIG/0ZZHjsRzKKauOTmppQk40dgVsejpytIek9R+aH172gxJ
  62. 2n4Cx0UwduRU5x8FFQlNc/kl722B0JWfJuB/snOZXv6LJ4o5aObIkozt2w9tVFeAqjYn2S
  63. 1UsNOfRHBXGsTYwpRDwFWP56nKo2d2wBBTHDhCy6fb2dLW1fvSi/YspueOGIlHpvlYKi2/
  64. CWqvs9xVrwcScMtiDoQYq0khhO0efLCxvg/o+W9CLMVM2ms4G1zoSUQKN0oYWWQJyW4+VI
  65. YneWO8UpN0J3ElXKi7bhgAat7dBaM1g9IrAzk153DiEFZNsPxGOgL/+YdQN7zUBx/z7EkI
  66. jyv80RV7fpUXvcq2p+qNl6UVig3VSzRrnsaJkUWu/A0u59ha7ocv6NxDIXjxpIDJme16GF
  67. quiGVBQNnYJymS/vFEbGf6bgf7iRmMCRUMG4nqLA6fPYP9uAtch+CmDfVLZC/fIdC5AAAA
  68. wQCDissV4zH6bfqgxJSuYNk8Vbb+19cF3b7gH1rVlB3zxpCAgcRgMHC+dP1z2NRx7UW9MR
  69. nye6kjpkzZZ0OigLqo7TtEq8uTglD9o6W7mRXqhy5A/ySOmqPL3ernHHQhGuoNODYAHkOU
  70. u2Rh8HXi+VLwKZcLInPOYJvcuLG4DxN8WfeVvlMHwhAOaTNNOtL4XZDHQeIPc4qHmJymmv
  71. sV7GuyQ6yW5C10uoGdxRPd90Bh4z4h2bKfZFjvEBbSBVkqrlAAAADBAN/zNtNayd/dX7Cr
  72. Nb4sZuzCh+CW4BH8GOePZWNCATwBbNXBVb5cR+dmuTqYm+Ekz0VxVQRA1TvKncluJOQpoa
  73. Xj8r0xdIgqkehnfDPMKtYVor06B9Fl1jrXtXU0Vrr6QcBWruSVyK1ZxqcmcNK/+KolVepe
  74. A6vcl/iKaG4U7su166nxLST06M2EgcSVsFJHpKn5+WAXC+X0Gx8kNjWIIb3GpiChdc0xZD
  75. mq02xZthVJrTCVw/e7gfDoB2QRsNV8HwAAAMEAzsCghZVp+0YsYg9oOrw4tEqcbEXEMhwY
  76. 0jW8JNL8Spr1Ibp5Dw6bRSk5azARjmJtnMJhJ3oeHfF0eoISqcNuQXGndGQbVM9YzzAzc1
  77. NbbCNsVroqKlChT5wyPNGS+phi2bPARBno7WSDvshTZ7dAVEP2c9MJW0XwoSevwKlhgSdt
  78. RLFFQ/5nclJSdzPBOmQouC0OBcMFSrYtMeknJ4VvueVvve5HcHFaEsaMc7ABAGaLYaBQOm
  79. iixITGvaNZh/tjAAAACW5pY29sYUBwMQE=
  80. -----END OPENSSH PRIVATE KEY-----`
  81. configDir = ".."
  82. )
  83. var (
  84. allPerms = []string{dataprovider.PermAny}
  85. homeBasePath string
  86. scpPath string
  87. gitPath string
  88. sshPath string
  89. pubKeyPath string
  90. privateKeyPath string
  91. gitWrapPath string
  92. logFilePath string
  93. )
  94. func TestMain(m *testing.M) {
  95. logFilePath = filepath.Join(configDir, "sftpgo_sftpd_test.log")
  96. loginBannerFileName := "login_banner"
  97. loginBannerFile := filepath.Join(configDir, loginBannerFileName)
  98. ioutil.WriteFile(loginBannerFile, []byte("simple login banner\n"), 0777)
  99. logger.InitLogger(logFilePath, 5, 1, 28, false, zerolog.DebugLevel)
  100. config.LoadConfig(configDir, "")
  101. providerConf := config.GetProviderConf()
  102. err := dataprovider.Initialize(providerConf, configDir)
  103. if err != nil {
  104. logger.Warn(logSender, "", "error initializing data provider: %v", err)
  105. os.Exit(1)
  106. }
  107. dataProvider := dataprovider.GetProvider()
  108. sftpdConf := config.GetSFTPDConfig()
  109. httpdConf := config.GetHTTPDConfig()
  110. sftpdConf.BindPort = 2022
  111. sftpdConf.KexAlgorithms = []string{"[email protected]", "ecdh-sha2-nistp256",
  112. "ecdh-sha2-nistp384"}
  113. sftpdConf.Ciphers = []string{"[email protected]", "[email protected]",
  114. "aes256-ctr"}
  115. sftpdConf.MACs = []string{"[email protected]", "hmac-sha2-256"}
  116. sftpdConf.LoginBannerFile = loginBannerFileName
  117. // we need to test all supported ssh commands
  118. sftpdConf.EnabledSSHCommands = []string{"*"}
  119. // we run the test cases with UploadMode atomic and resume support. The non atomic code path
  120. // simply does not execute some code so if it works in atomic mode will
  121. // work in non atomic mode too
  122. sftpdConf.UploadMode = 2
  123. homeBasePath = os.TempDir()
  124. var scriptArgs string
  125. if runtime.GOOS == "windows" {
  126. scriptArgs = "%*"
  127. } else {
  128. sftpdConf.Actions.ExecuteOn = []string{"download", "upload", "rename", "delete", "ssh_cmd"}
  129. sftpdConf.Actions.Command = "/usr/bin/true"
  130. sftpdConf.Actions.HTTPNotificationURL = "http://127.0.0.1:8080/"
  131. scriptArgs = "$@"
  132. }
  133. scpPath, err = exec.LookPath("scp")
  134. if err != nil {
  135. logger.Warn(logSender, "", "unable to get scp command. SCP tests will be skipped, err: %v", err)
  136. logger.WarnToConsole("unable to get scp command. SCP tests will be skipped, err: %v", err)
  137. scpPath = ""
  138. }
  139. gitPath, err = exec.LookPath("git")
  140. if err != nil {
  141. logger.Warn(logSender, "", "unable to get git command. GIT tests will be skipped, err: %v", err)
  142. logger.WarnToConsole("unable to get git command. GIT tests will be skipped, err: %v", err)
  143. gitPath = ""
  144. }
  145. sshPath, err = exec.LookPath("ssh")
  146. if err != nil {
  147. logger.Warn(logSender, "", "unable to get ssh command. GIT tests will be skipped, err: %v", err)
  148. logger.WarnToConsole("unable to get ssh command. GIT tests will be skipped, err: %v", err)
  149. gitPath = ""
  150. }
  151. pubKeyPath = filepath.Join(homeBasePath, "ssh_key.pub")
  152. privateKeyPath = filepath.Join(homeBasePath, "ssh_key")
  153. gitWrapPath = filepath.Join(homeBasePath, "gitwrap.sh")
  154. err = ioutil.WriteFile(pubKeyPath, []byte(testPubKey+"\n"), 0600)
  155. if err != nil {
  156. logger.WarnToConsole("unable to save public key to file: %v", err)
  157. }
  158. err = ioutil.WriteFile(privateKeyPath, []byte(testPrivateKey+"\n"), 0600)
  159. if err != nil {
  160. logger.WarnToConsole("unable to save private key to file: %v", err)
  161. }
  162. err = ioutil.WriteFile(gitWrapPath, []byte(fmt.Sprintf("%v -i %v -oStrictHostKeyChecking=no %v\n",
  163. sshPath, privateKeyPath, scriptArgs)), 0755)
  164. if err != nil {
  165. logger.WarnToConsole("unable to save gitwrap shell script: %v", err)
  166. }
  167. sftpd.SetDataProvider(dataProvider)
  168. httpd.SetDataProvider(dataProvider)
  169. go func() {
  170. logger.Debug(logSender, "", "initializing SFTP server with config %+v", sftpdConf)
  171. if err := sftpdConf.Initialize(configDir); err != nil {
  172. logger.Error(logSender, "", "could not start SFTP server: %v", err)
  173. }
  174. }()
  175. go func() {
  176. if err := httpdConf.Initialize(configDir); err != nil {
  177. logger.Error(logSender, "", "could not start HTTP server: %v", err)
  178. }
  179. }()
  180. waitTCPListening(fmt.Sprintf("%s:%d", sftpdConf.BindAddress, sftpdConf.BindPort))
  181. waitTCPListening(fmt.Sprintf("%s:%d", httpdConf.BindAddress, httpdConf.BindPort))
  182. exitCode := m.Run()
  183. os.Remove(logFilePath)
  184. os.Remove(loginBannerFile)
  185. os.Remove(pubKeyPath)
  186. os.Remove(privateKeyPath)
  187. os.Remove(gitWrapPath)
  188. os.Exit(exitCode)
  189. }
  190. func TestInitialization(t *testing.T) {
  191. config.LoadConfig(configDir, "")
  192. sftpdConf := config.GetSFTPDConfig()
  193. sftpdConf.Umask = "invalid umask"
  194. sftpdConf.BindPort = 2022
  195. sftpdConf.LoginBannerFile = "invalid_file"
  196. sftpdConf.IsSCPEnabled = true
  197. sftpdConf.EnabledSSHCommands = append(sftpdConf.EnabledSSHCommands, "ls")
  198. err := sftpdConf.Initialize(configDir)
  199. if err == nil {
  200. t.Errorf("Inizialize must fail, a SFTP server should be already running")
  201. }
  202. }
  203. func TestBasicSFTPHandling(t *testing.T) {
  204. usePubKey := false
  205. u := getTestUser(usePubKey)
  206. u.QuotaSize = 6553600
  207. user, _, err := httpd.AddUser(u, http.StatusOK)
  208. if err != nil {
  209. t.Errorf("unable to add user: %v", err)
  210. }
  211. os.RemoveAll(user.GetHomeDir())
  212. client, err := getSftpClient(user, usePubKey)
  213. if err != nil {
  214. t.Errorf("unable to create sftp client: %v", err)
  215. } else {
  216. defer client.Close()
  217. testFileName := "test_file.dat"
  218. testFilePath := filepath.Join(homeBasePath, testFileName)
  219. testFileSize := int64(65535)
  220. expectedQuotaSize := user.UsedQuotaSize + testFileSize
  221. expectedQuotaFiles := user.UsedQuotaFiles + 1
  222. createTestFile(testFilePath, testFileSize)
  223. err = sftpUploadFile(testFilePath, path.Join("/missing_dir", testFileName), testFileSize, client)
  224. if err == nil {
  225. t.Errorf("upload a file to a missing dir must fail")
  226. }
  227. err = sftpUploadFile(testFilePath, testFileName, testFileSize, client)
  228. if err != nil {
  229. t.Errorf("file upload error: %v", err)
  230. }
  231. localDownloadPath := filepath.Join(homeBasePath, "test_download.dat")
  232. err = sftpDownloadFile(testFileName, localDownloadPath, testFileSize, client)
  233. if err != nil {
  234. t.Errorf("file download error: %v", err)
  235. }
  236. user, _, err = httpd.GetUserByID(user.ID, http.StatusOK)
  237. if err != nil {
  238. t.Errorf("error getting user: %v", err)
  239. }
  240. if expectedQuotaFiles != user.UsedQuotaFiles {
  241. t.Errorf("quota files does not match, expected: %v, actual: %v", expectedQuotaFiles, user.UsedQuotaFiles)
  242. }
  243. if expectedQuotaSize != user.UsedQuotaSize {
  244. t.Errorf("quota size does not match, expected: %v, actual: %v", expectedQuotaSize, user.UsedQuotaSize)
  245. }
  246. err = client.Remove(testFileName)
  247. if err != nil {
  248. t.Errorf("error removing uploaded file: %v", err)
  249. }
  250. _, err = client.Lstat(testFileName)
  251. if err == nil {
  252. t.Errorf("stat for deleted file must not succeed")
  253. }
  254. user, _, err = httpd.GetUserByID(user.ID, http.StatusOK)
  255. if err != nil {
  256. t.Errorf("error getting user: %v", err)
  257. }
  258. if (expectedQuotaFiles - 1) != user.UsedQuotaFiles {
  259. t.Errorf("quota files does not match after delete, expected: %v, actual: %v", expectedQuotaFiles-1, user.UsedQuotaFiles)
  260. }
  261. if (expectedQuotaSize - testFileSize) != user.UsedQuotaSize {
  262. t.Errorf("quota size does not match, expected: %v, actual: %v", expectedQuotaSize-testFileSize, user.UsedQuotaSize)
  263. }
  264. os.Remove(testFilePath)
  265. os.Remove(localDownloadPath)
  266. }
  267. _, err = httpd.RemoveUser(user, http.StatusOK)
  268. if err != nil {
  269. t.Errorf("unable to remove user: %v", err)
  270. }
  271. os.RemoveAll(user.GetHomeDir())
  272. }
  273. func TestUploadResume(t *testing.T) {
  274. usePubKey := false
  275. u := getTestUser(usePubKey)
  276. user, _, err := httpd.AddUser(u, http.StatusOK)
  277. if err != nil {
  278. t.Errorf("unable to add user: %v", err)
  279. }
  280. os.RemoveAll(user.GetHomeDir())
  281. client, err := getSftpClient(user, usePubKey)
  282. if err != nil {
  283. t.Errorf("unable to create sftp client: %v", err)
  284. } else {
  285. defer client.Close()
  286. testFileName := "test_file.dat"
  287. testFilePath := filepath.Join(homeBasePath, testFileName)
  288. testFileSize := int64(65535)
  289. appendDataSize := int64(65535)
  290. err = createTestFile(testFilePath, testFileSize)
  291. if err != nil {
  292. t.Errorf("unable to create test file: %v", err)
  293. }
  294. err = sftpUploadFile(testFilePath, testFileName, testFileSize, client)
  295. if err != nil {
  296. t.Errorf("file upload error: %v", err)
  297. }
  298. err = appendToTestFile(testFilePath, appendDataSize)
  299. if err != nil {
  300. t.Errorf("unable to append to test file: %v", err)
  301. }
  302. err = sftpUploadResumeFile(testFilePath, testFileName, testFileSize+appendDataSize, false, client)
  303. if err != nil {
  304. t.Errorf("file upload resume error: %v", err)
  305. }
  306. localDownloadPath := filepath.Join(homeBasePath, "test_download.dat")
  307. err = sftpDownloadFile(testFileName, localDownloadPath, testFileSize+appendDataSize, client)
  308. if err != nil {
  309. t.Errorf("file download error: %v", err)
  310. }
  311. initialHash, err := computeHashForFile(sha256.New(), testFilePath)
  312. if err != nil {
  313. t.Errorf("error computing file hash: %v", err)
  314. }
  315. donwloadedFileHash, err := computeHashForFile(sha256.New(), localDownloadPath)
  316. if err != nil {
  317. t.Errorf("error computing downloaded file hash: %v", err)
  318. }
  319. if donwloadedFileHash != initialHash {
  320. t.Errorf("resume failed: file hash does not match")
  321. }
  322. err = sftpUploadResumeFile(testFilePath, testFileName, testFileSize+appendDataSize, true, client)
  323. if err == nil {
  324. t.Errorf("file upload resume with invalid offset must fail")
  325. }
  326. os.Remove(testFilePath)
  327. os.Remove(localDownloadPath)
  328. }
  329. _, err = httpd.RemoveUser(user, http.StatusOK)
  330. if err != nil {
  331. t.Errorf("unable to remove user: %v", err)
  332. }
  333. os.RemoveAll(user.GetHomeDir())
  334. }
  335. func TestDirCommands(t *testing.T) {
  336. usePubKey := false
  337. user, _, err := httpd.AddUser(getTestUser(usePubKey), http.StatusOK)
  338. if err != nil {
  339. t.Errorf("unable to add user: %v", err)
  340. }
  341. // remove the home dir to test auto creation
  342. os.RemoveAll(user.HomeDir)
  343. client, err := getSftpClient(user, usePubKey)
  344. if err != nil {
  345. t.Errorf("unable to create sftp client: %v", err)
  346. } else {
  347. defer client.Close()
  348. err = client.Mkdir("test1")
  349. if err != nil {
  350. t.Errorf("error mkdir: %v", err)
  351. }
  352. err = client.Rename("test1", "test")
  353. if err != nil {
  354. t.Errorf("error rename: %v", err)
  355. }
  356. _, err = client.Lstat("/test1")
  357. if err == nil {
  358. t.Errorf("stat for renamed dir must not succeed")
  359. }
  360. err = client.PosixRename("test", "test1")
  361. if err != nil {
  362. t.Errorf("error posix rename: %v", err)
  363. }
  364. err = client.Remove("test1")
  365. if err != nil {
  366. t.Errorf("error rmdir: %v", err)
  367. }
  368. err = client.Mkdir("/test/test1")
  369. if err == nil {
  370. t.Errorf("recursive mkdir must fail")
  371. }
  372. client.Mkdir("/test")
  373. err = client.Mkdir("/test/test1")
  374. if err != nil {
  375. t.Errorf("mkdir dir error: %v", err)
  376. }
  377. _, err = client.ReadDir("/this/dir/does/not/exist")
  378. if err == nil {
  379. t.Errorf("reading a missing dir must fail")
  380. }
  381. err = client.RemoveDirectory("/test/test1")
  382. if err != nil {
  383. t.Errorf("remove dir error: %v", err)
  384. }
  385. err = client.RemoveDirectory("/test")
  386. if err != nil {
  387. t.Errorf("remove dir error: %v", err)
  388. }
  389. _, err = client.Lstat("/test")
  390. if err == nil {
  391. t.Errorf("stat for deleted dir must not succeed")
  392. }
  393. err = client.RemoveDirectory("/test")
  394. if err == nil {
  395. t.Errorf("remove missing path must fail")
  396. }
  397. }
  398. httpd.RemoveUser(user, http.StatusOK)
  399. os.RemoveAll(user.GetHomeDir())
  400. }
  401. func TestRemove(t *testing.T) {
  402. usePubKey := true
  403. user, _, err := httpd.AddUser(getTestUser(usePubKey), http.StatusOK)
  404. if err != nil {
  405. t.Errorf("unable to add user: %v", err)
  406. }
  407. client, err := getSftpClient(user, usePubKey)
  408. if err != nil {
  409. t.Errorf("unable to create sftp client: %v", err)
  410. } else {
  411. defer client.Close()
  412. err = client.Mkdir("test")
  413. if err != nil {
  414. t.Errorf("error mkdir: %v", err)
  415. }
  416. err = client.Mkdir("/test/test1")
  417. if err != nil {
  418. t.Errorf("error mkdir subdir: %v", err)
  419. }
  420. testFileName := "/test_file.dat"
  421. testFilePath := filepath.Join(homeBasePath, testFileName)
  422. testFileSize := int64(65535)
  423. err = createTestFile(testFilePath, testFileSize)
  424. if err != nil {
  425. t.Errorf("unable to create test file: %v", err)
  426. }
  427. err = sftpUploadFile(testFilePath, path.Join("/test", testFileName), testFileSize, client)
  428. if err != nil {
  429. t.Errorf("file upload error: %v", err)
  430. }
  431. err = client.Remove("/test")
  432. if err == nil {
  433. t.Errorf("remove non empty dir must fail")
  434. }
  435. err = client.RemoveDirectory(path.Join("/test", testFileName))
  436. if err == nil {
  437. t.Errorf("remove a file with rmdir must fail")
  438. }
  439. err = client.Remove(path.Join("/test", testFileName))
  440. if err != nil {
  441. t.Errorf("remove file error: %v", err)
  442. }
  443. err = client.Remove(path.Join("/test", testFileName))
  444. if err == nil {
  445. t.Errorf("remove missing file must fail")
  446. }
  447. err = client.Remove("/test/test1")
  448. if err != nil {
  449. t.Errorf("remove dir error: %v", err)
  450. }
  451. err = client.Remove("/test")
  452. if err != nil {
  453. t.Errorf("remove dir error: %v", err)
  454. }
  455. os.Remove(testFilePath)
  456. }
  457. _, err = httpd.RemoveUser(user, http.StatusOK)
  458. if err != nil {
  459. t.Errorf("unable to remove user: %v", err)
  460. }
  461. os.RemoveAll(user.GetHomeDir())
  462. }
  463. func TestLink(t *testing.T) {
  464. usePubKey := false
  465. user, _, err := httpd.AddUser(getTestUser(usePubKey), http.StatusOK)
  466. if err != nil {
  467. t.Errorf("unable to add user: %v", err)
  468. }
  469. client, err := getSftpClient(user, usePubKey)
  470. if err != nil {
  471. t.Errorf("unable to create sftp client: %v", err)
  472. } else {
  473. defer client.Close()
  474. testFileName := "test_file.dat"
  475. testFilePath := filepath.Join(homeBasePath, testFileName)
  476. testFileSize := int64(65535)
  477. err = createTestFile(testFilePath, testFileSize)
  478. if err != nil {
  479. t.Errorf("unable to create test file: %v", err)
  480. }
  481. err = sftpUploadFile(testFilePath, testFileName, testFileSize, client)
  482. if err != nil {
  483. t.Errorf("file upload error: %v", err)
  484. }
  485. err = client.Symlink(testFileName, testFileName+".link")
  486. if err != nil {
  487. t.Errorf("error creating symlink: %v", err)
  488. }
  489. _, err = client.ReadLink(testFileName + ".link")
  490. if err == nil {
  491. t.Errorf("readlink is currently not implemented so must fail")
  492. }
  493. err = client.Symlink(testFileName, testFileName+".link")
  494. if err == nil {
  495. t.Errorf("creating a symlink to an existing one must fail")
  496. }
  497. err = client.Link(testFileName, testFileName+".hlink")
  498. if err == nil {
  499. t.Errorf("hard link is not supported and must fail")
  500. }
  501. err = client.Remove(testFileName + ".link")
  502. if err != nil {
  503. t.Errorf("error removing symlink: %v", err)
  504. }
  505. err = client.Remove(testFileName)
  506. if err != nil {
  507. t.Errorf("error removing uploaded file: %v", err)
  508. }
  509. os.Remove(testFilePath)
  510. }
  511. _, err = httpd.RemoveUser(user, http.StatusOK)
  512. if err != nil {
  513. t.Errorf("unable to remove user: %v", err)
  514. }
  515. os.RemoveAll(user.GetHomeDir())
  516. }
  517. func TestStat(t *testing.T) {
  518. usePubKey := false
  519. user, _, err := httpd.AddUser(getTestUser(usePubKey), http.StatusOK)
  520. if err != nil {
  521. t.Errorf("unable to add user: %v", err)
  522. }
  523. client, err := getSftpClient(user, usePubKey)
  524. if err != nil {
  525. t.Errorf("unable to create sftp client: %v", err)
  526. } else {
  527. defer client.Close()
  528. testFileName := "test_file.dat"
  529. testFilePath := filepath.Join(homeBasePath, testFileName)
  530. testFileSize := int64(65535)
  531. createTestFile(testFilePath, testFileSize)
  532. err = sftpUploadFile(testFilePath, testFileName, testFileSize, client)
  533. if err != nil {
  534. t.Errorf("file upload error: %v", err)
  535. }
  536. _, err := client.Lstat(testFileName)
  537. if err != nil {
  538. t.Errorf("stat error: %v", err)
  539. }
  540. // mode 0666 and 0444 works on Windows too
  541. newPerm := os.FileMode(0666)
  542. err = client.Chmod(testFileName, newPerm)
  543. if err != nil {
  544. t.Errorf("chmod error: %v", err)
  545. }
  546. newFi, err := client.Lstat(testFileName)
  547. if err != nil {
  548. t.Errorf("stat error: %v", err)
  549. }
  550. if newPerm != newFi.Mode().Perm() {
  551. t.Errorf("chmod failed expected: %v, actual: %v", newPerm, newFi.Mode().Perm())
  552. }
  553. newPerm = os.FileMode(0444)
  554. err = client.Chmod(testFileName, newPerm)
  555. if err != nil {
  556. t.Errorf("chmod error: %v", err)
  557. }
  558. newFi, err = client.Lstat(testFileName)
  559. if err != nil {
  560. t.Errorf("stat error: %v", err)
  561. }
  562. if newPerm != newFi.Mode().Perm() {
  563. t.Errorf("chmod failed expected: %v, actual: %v", newPerm, newFi.Mode().Perm())
  564. }
  565. _, err = client.ReadLink(testFileName)
  566. if err == nil {
  567. t.Errorf("readlink is not supported and must fail")
  568. }
  569. err = client.Truncate(testFileName, 0)
  570. if err != nil {
  571. t.Errorf("truncate must be silently ignored: %v", err)
  572. }
  573. os.Remove(testFilePath)
  574. }
  575. _, err = httpd.RemoveUser(user, http.StatusOK)
  576. if err != nil {
  577. t.Errorf("unable to remove user: %v", err)
  578. }
  579. os.RemoveAll(user.GetHomeDir())
  580. }
  581. func TestStatChownChmod(t *testing.T) {
  582. if runtime.GOOS == "windows" {
  583. t.Skip("chown is not supported on Windows, chmod is partially supported")
  584. }
  585. usePubKey := true
  586. user, _, err := httpd.AddUser(getTestUser(usePubKey), http.StatusOK)
  587. if err != nil {
  588. t.Errorf("unable to add user: %v", err)
  589. }
  590. client, err := getSftpClient(user, usePubKey)
  591. if err != nil {
  592. t.Errorf("unable to create sftp client: %v", err)
  593. } else {
  594. defer client.Close()
  595. testFileName := "test_file.dat"
  596. testFilePath := filepath.Join(homeBasePath, testFileName)
  597. testFileSize := int64(65535)
  598. createTestFile(testFilePath, testFileSize)
  599. err = sftpUploadFile(testFilePath, testFileName, testFileSize, client)
  600. if err != nil {
  601. t.Errorf("file upload error: %v", err)
  602. }
  603. err = client.Chown(testFileName, os.Getuid(), os.Getgid())
  604. if err != nil {
  605. t.Errorf("chown error: %v", err)
  606. }
  607. newPerm := os.FileMode(0600)
  608. err = client.Chmod(testFileName, newPerm)
  609. if err != nil {
  610. t.Errorf("chmod error: %v", err)
  611. }
  612. newFi, err := client.Lstat(testFileName)
  613. if err != nil {
  614. t.Errorf("stat error: %v", err)
  615. }
  616. if newPerm != newFi.Mode().Perm() {
  617. t.Errorf("chown failed expected: %v, actual: %v", newPerm, newFi.Mode().Perm())
  618. }
  619. err = client.Remove(testFileName)
  620. if err != nil {
  621. t.Errorf("error removing uploaded file: %v", err)
  622. }
  623. // l'errore viene riconvertito da sftp.ErrSSHFxNoSuchFile in os.ErrNotExist
  624. err = client.Chmod(testFileName, newPerm)
  625. if err != os.ErrNotExist {
  626. t.Errorf("unexpected chmod error: %v expected: %v", err, os.ErrNotExist)
  627. }
  628. err = client.Chown(testFileName, os.Getuid(), os.Getgid())
  629. if err != os.ErrNotExist {
  630. t.Errorf("unexpected chown error: %v expected: %v", err, os.ErrNotExist)
  631. }
  632. os.Remove(testFilePath)
  633. }
  634. _, err = httpd.RemoveUser(user, http.StatusOK)
  635. if err != nil {
  636. t.Errorf("unable to remove user: %v", err)
  637. }
  638. os.RemoveAll(user.GetHomeDir())
  639. }
  640. func TestChtimes(t *testing.T) {
  641. usePubKey := false
  642. user, _, err := httpd.AddUser(getTestUser(usePubKey), http.StatusOK)
  643. if err != nil {
  644. t.Errorf("unable to add user: %v", err)
  645. }
  646. client, err := getSftpClient(user, usePubKey)
  647. if err != nil {
  648. t.Errorf("unable to create sftp client: %v", err)
  649. } else {
  650. defer client.Close()
  651. testFileName := "test_file.dat"
  652. testFilePath := filepath.Join(homeBasePath, testFileName)
  653. testFileSize := int64(65535)
  654. testDir := "test"
  655. createTestFile(testFilePath, testFileSize)
  656. err = sftpUploadFile(testFilePath, testFileName, testFileSize, client)
  657. if err != nil {
  658. t.Errorf("file upload error: %v", err)
  659. }
  660. acmodTime := time.Now()
  661. err = client.Chtimes(testFileName, acmodTime, acmodTime)
  662. if err != nil {
  663. t.Errorf("error changing file times")
  664. }
  665. newFi, err := client.Lstat(testFileName)
  666. if err != nil {
  667. t.Errorf("file stat error: %v", err)
  668. }
  669. diff := math.Abs(newFi.ModTime().Sub(acmodTime).Seconds())
  670. if diff > 1 {
  671. t.Errorf("diff between wanted and real modification time too big: %v", diff)
  672. }
  673. err = client.Chtimes("invalidFile", acmodTime, acmodTime)
  674. if !os.IsNotExist(err) {
  675. t.Errorf("unexpected error: %v", err)
  676. }
  677. err = client.Mkdir(testDir)
  678. if err != nil {
  679. t.Errorf("unable to create dir: %v", err)
  680. }
  681. err = client.Chtimes(testDir, acmodTime, acmodTime)
  682. if err != nil {
  683. t.Errorf("error changing dir times")
  684. }
  685. newFi, err = client.Lstat(testDir)
  686. if err != nil {
  687. t.Errorf("dir stat error: %v", err)
  688. }
  689. diff = math.Abs(newFi.ModTime().Sub(acmodTime).Seconds())
  690. if diff > 1 {
  691. t.Errorf("diff between wanted and real modification time too big: %v", diff)
  692. }
  693. os.Remove(testFilePath)
  694. }
  695. _, err = httpd.RemoveUser(user, http.StatusOK)
  696. if err != nil {
  697. t.Errorf("unable to remove user: %v", err)
  698. }
  699. os.RemoveAll(user.GetHomeDir())
  700. }
  701. // basic tests to verify virtual chroot, should be improved to cover more cases ...
  702. func TestEscapeHomeDir(t *testing.T) {
  703. usePubKey := true
  704. user, _, err := httpd.AddUser(getTestUser(usePubKey), http.StatusOK)
  705. if err != nil {
  706. t.Errorf("unable to add user: %v", err)
  707. }
  708. client, err := getSftpClient(user, usePubKey)
  709. if err != nil {
  710. t.Errorf("unable to create sftp client: %v", err)
  711. } else {
  712. defer client.Close()
  713. _, err := client.Getwd()
  714. if err != nil {
  715. t.Errorf("unable to get working dir: %v", err)
  716. }
  717. testDir := "testDir"
  718. linkPath := filepath.Join(homeBasePath, defaultUsername, testDir)
  719. err = os.Symlink(homeBasePath, linkPath)
  720. if err != nil {
  721. t.Errorf("error making local symlink: %v", err)
  722. }
  723. _, err = client.ReadDir(testDir)
  724. if err == nil {
  725. t.Errorf("reading a symbolic link outside home dir should not succeeded")
  726. }
  727. os.Remove(linkPath)
  728. testFileName := "test_file.dat"
  729. testFilePath := filepath.Join(homeBasePath, testFileName)
  730. testFileSize := int64(65535)
  731. err = createTestFile(testFilePath, testFileSize)
  732. if err != nil {
  733. t.Errorf("unable to create test file: %v", err)
  734. }
  735. remoteDestPath := path.Join("..", "..", testFileName)
  736. err = sftpUploadFile(testFilePath, remoteDestPath, testFileSize, client)
  737. if err != nil {
  738. t.Errorf("file upload error: %v", err)
  739. }
  740. _, err = client.Lstat(testFileName)
  741. if err != nil {
  742. t.Errorf("file stat error: %v the file was created outside the user dir!", err)
  743. }
  744. err = client.Remove(testFileName)
  745. if err != nil {
  746. t.Errorf("error removing uploaded file: %v", err)
  747. }
  748. linkPath = filepath.Join(homeBasePath, defaultUsername, testFileName)
  749. err = os.Symlink(homeBasePath, linkPath)
  750. if err != nil {
  751. t.Errorf("error making local symlink: %v", err)
  752. }
  753. err = sftpDownloadFile(testFileName, testFilePath, 0, client)
  754. if err == nil {
  755. t.Errorf("download file outside home dir must fail")
  756. }
  757. err = sftpUploadFile(testFilePath, remoteDestPath, testFileSize, client)
  758. if err == nil {
  759. t.Errorf("overwrite a file outside home dir must fail")
  760. }
  761. err = client.Chmod(remoteDestPath, 0644)
  762. if err == nil {
  763. t.Errorf("setstat on a file outside home dir must fail")
  764. }
  765. os.Remove(linkPath)
  766. os.Remove(testFilePath)
  767. }
  768. _, err = httpd.RemoveUser(user, http.StatusOK)
  769. if err != nil {
  770. t.Errorf("unable to remove user: %v", err)
  771. }
  772. os.RemoveAll(user.GetHomeDir())
  773. }
  774. func TestHomeSpecialChars(t *testing.T) {
  775. usePubKey := true
  776. u := getTestUser(usePubKey)
  777. u.HomeDir = filepath.Join(homeBasePath, "abc açà#&%lk")
  778. user, _, err := httpd.AddUser(u, http.StatusOK)
  779. if err != nil {
  780. t.Errorf("unable to add user: %v", err)
  781. }
  782. client, err := getSftpClient(user, usePubKey)
  783. if err != nil {
  784. t.Errorf("unable to create sftp client: %v", err)
  785. } else {
  786. defer client.Close()
  787. _, err := client.Getwd()
  788. if err != nil {
  789. t.Errorf("unable to get working dir: %v", err)
  790. }
  791. testFileName := "test_file.dat"
  792. testFilePath := filepath.Join(homeBasePath, testFileName)
  793. testFileSize := int64(65535)
  794. err = createTestFile(testFilePath, testFileSize)
  795. if err != nil {
  796. t.Errorf("unable to create test file: %v", err)
  797. }
  798. err = sftpUploadFile(testFilePath, testFileName, testFileSize, client)
  799. if err != nil {
  800. t.Errorf("file upload error: %v", err)
  801. }
  802. files, err := client.ReadDir(".")
  803. if err != nil {
  804. t.Errorf("unable to read remote dir: %v", err)
  805. }
  806. if len(files) < 1 {
  807. t.Errorf("expected at least 1 file in this dir")
  808. }
  809. err = client.Remove(testFileName)
  810. if err != nil {
  811. t.Errorf("error removing uploaded file: %v", err)
  812. }
  813. os.Remove(testFilePath)
  814. }
  815. _, err = httpd.RemoveUser(user, http.StatusOK)
  816. if err != nil {
  817. t.Errorf("unable to remove user: %v", err)
  818. }
  819. os.RemoveAll(user.GetHomeDir())
  820. }
  821. func TestLogin(t *testing.T) {
  822. u := getTestUser(false)
  823. u.PublicKeys = []string{testPubKey}
  824. user, _, err := httpd.AddUser(u, http.StatusOK)
  825. if err != nil {
  826. t.Errorf("unable to add user: %v", err)
  827. }
  828. client, err := getSftpClient(user, false)
  829. if err != nil {
  830. t.Errorf("unable to create sftp client: %v", err)
  831. } else {
  832. defer client.Close()
  833. _, err := client.Getwd()
  834. if err != nil {
  835. t.Errorf("sftp client with valid password must work")
  836. }
  837. user, _, err = httpd.GetUserByID(user.ID, http.StatusOK)
  838. if err != nil {
  839. t.Errorf("error getting user: %v", err)
  840. }
  841. if user.LastLogin <= 0 {
  842. t.Errorf("last login must be updated after a successful login: %v", user.LastLogin)
  843. }
  844. }
  845. client, err = getSftpClient(user, true)
  846. if err != nil {
  847. t.Errorf("unable to create sftp client: %v", err)
  848. } else {
  849. defer client.Close()
  850. _, err := client.Getwd()
  851. if err != nil {
  852. t.Errorf("sftp client with valid public key must work")
  853. }
  854. }
  855. user.Password = "invalid password"
  856. client, err = getSftpClient(user, false)
  857. if err == nil {
  858. t.Errorf("login with invalid password must fail")
  859. defer client.Close()
  860. }
  861. // testPubKey1 is not authorized
  862. user.PublicKeys = []string{testPubKey1}
  863. user.Password = ""
  864. _, _, err = httpd.UpdateUser(user, http.StatusOK)
  865. if err != nil {
  866. t.Errorf("unable to update user: %v", err)
  867. }
  868. client, err = getSftpClient(user, true)
  869. if err == nil {
  870. t.Errorf("login with invalid public key must fail")
  871. defer client.Close()
  872. }
  873. // login a user with multiple public keys, only the second one is valid
  874. user.PublicKeys = []string{testPubKey1, testPubKey}
  875. user.Password = ""
  876. _, _, err = httpd.UpdateUser(user, http.StatusOK)
  877. if err != nil {
  878. t.Errorf("unable to update user: %v", err)
  879. }
  880. client, err = getSftpClient(user, true)
  881. if err != nil {
  882. t.Errorf("unable to create sftp client: %v", err)
  883. } else {
  884. defer client.Close()
  885. _, err := client.Getwd()
  886. if err != nil {
  887. t.Errorf("sftp client with multiple public key must work if at least one public key is valid")
  888. }
  889. }
  890. _, err = httpd.RemoveUser(user, http.StatusOK)
  891. if err != nil {
  892. t.Errorf("unable to remove user: %v", err)
  893. }
  894. os.RemoveAll(user.GetHomeDir())
  895. }
  896. func TestLoginUserStatus(t *testing.T) {
  897. usePubKey := true
  898. user, _, err := httpd.AddUser(getTestUser(usePubKey), http.StatusOK)
  899. if err != nil {
  900. t.Errorf("unable to add user: %v", err)
  901. }
  902. client, err := getSftpClient(user, usePubKey)
  903. if err != nil {
  904. t.Errorf("unable to create sftp client: %v", err)
  905. } else {
  906. defer client.Close()
  907. _, err := client.Getwd()
  908. if err != nil {
  909. t.Errorf("sftp client with valid credentials must work")
  910. }
  911. user, _, err = httpd.GetUserByID(user.ID, http.StatusOK)
  912. if err != nil {
  913. t.Errorf("error getting user: %v", err)
  914. }
  915. if user.LastLogin <= 0 {
  916. t.Errorf("last login must be updated after a successful login: %v", user.LastLogin)
  917. }
  918. }
  919. user.Status = 0
  920. user, _, err = httpd.UpdateUser(user, http.StatusOK)
  921. if err != nil {
  922. t.Errorf("unable to update user: %v", err)
  923. }
  924. client, err = getSftpClient(user, usePubKey)
  925. if err == nil {
  926. t.Errorf("login for a disabled user must fail")
  927. defer client.Close()
  928. }
  929. _, err = httpd.RemoveUser(user, http.StatusOK)
  930. if err != nil {
  931. t.Errorf("unable to remove user: %v", err)
  932. }
  933. os.RemoveAll(user.GetHomeDir())
  934. }
  935. func TestLoginUserExpiration(t *testing.T) {
  936. usePubKey := true
  937. user, _, err := httpd.AddUser(getTestUser(usePubKey), http.StatusOK)
  938. if err != nil {
  939. t.Errorf("unable to add user: %v", err)
  940. }
  941. client, err := getSftpClient(user, usePubKey)
  942. if err != nil {
  943. t.Errorf("unable to create sftp client: %v", err)
  944. } else {
  945. defer client.Close()
  946. _, err := client.Getwd()
  947. if err != nil {
  948. t.Errorf("sftp client with valid credentials must work")
  949. }
  950. user, _, err = httpd.GetUserByID(user.ID, http.StatusOK)
  951. if err != nil {
  952. t.Errorf("error getting user: %v", err)
  953. }
  954. if user.LastLogin <= 0 {
  955. t.Errorf("last login must be updated after a successful login: %v", user.LastLogin)
  956. }
  957. }
  958. user.ExpirationDate = utils.GetTimeAsMsSinceEpoch(time.Now()) - 120000
  959. user, _, err = httpd.UpdateUser(user, http.StatusOK)
  960. if err != nil {
  961. t.Errorf("unable to update user: %v", err)
  962. }
  963. client, err = getSftpClient(user, usePubKey)
  964. if err == nil {
  965. t.Errorf("login for an expired user must fail")
  966. defer client.Close()
  967. }
  968. user.ExpirationDate = utils.GetTimeAsMsSinceEpoch(time.Now()) + 120000
  969. _, _, err = httpd.UpdateUser(user, http.StatusOK)
  970. if err != nil {
  971. t.Errorf("unable to update user: %v", err)
  972. }
  973. client, err = getSftpClient(user, usePubKey)
  974. if err != nil {
  975. t.Errorf("login for a non expired user must succeed: %v", err)
  976. } else {
  977. defer client.Close()
  978. }
  979. _, err = httpd.RemoveUser(user, http.StatusOK)
  980. if err != nil {
  981. t.Errorf("unable to remove user: %v", err)
  982. }
  983. os.RemoveAll(user.GetHomeDir())
  984. }
  985. func TestLoginWithIPFilters(t *testing.T) {
  986. usePubKey := true
  987. u := getTestUser(usePubKey)
  988. u.Filters.DeniedIP = []string{"192.167.0.0/24", "172.18.0.0/16"}
  989. u.Filters.AllowedIP = []string{}
  990. user, _, err := httpd.AddUser(u, http.StatusOK)
  991. if err != nil {
  992. t.Errorf("unable to add user: %v", err)
  993. }
  994. client, err := getSftpClient(user, usePubKey)
  995. if err != nil {
  996. t.Errorf("unable to create sftp client: %v", err)
  997. } else {
  998. defer client.Close()
  999. _, err := client.Getwd()
  1000. if err != nil {
  1001. t.Errorf("sftp client with valid credentials must work")
  1002. }
  1003. user, _, err = httpd.GetUserByID(user.ID, http.StatusOK)
  1004. if err != nil {
  1005. t.Errorf("error getting user: %v", err)
  1006. }
  1007. if user.LastLogin <= 0 {
  1008. t.Errorf("last login must be updated after a successful login: %v", user.LastLogin)
  1009. }
  1010. }
  1011. user.Filters.AllowedIP = []string{"127.0.0.0/8"}
  1012. _, _, err = httpd.UpdateUser(user, http.StatusOK)
  1013. if err != nil {
  1014. t.Errorf("unable to update user: %v", err)
  1015. }
  1016. client, err = getSftpClient(user, usePubKey)
  1017. if err != nil {
  1018. t.Errorf("login from an allowed IP must succeed: %v", err)
  1019. } else {
  1020. defer client.Close()
  1021. }
  1022. user.Filters.AllowedIP = []string{"172.19.0.0/16"}
  1023. _, _, err = httpd.UpdateUser(user, http.StatusOK)
  1024. if err != nil {
  1025. t.Errorf("unable to update user: %v", err)
  1026. }
  1027. client, err = getSftpClient(user, usePubKey)
  1028. if err == nil {
  1029. t.Errorf("login from an not allowed IP must fail")
  1030. client.Close()
  1031. }
  1032. _, err = httpd.RemoveUser(user, http.StatusOK)
  1033. if err != nil {
  1034. t.Errorf("unable to remove user: %v", err)
  1035. }
  1036. os.RemoveAll(user.GetHomeDir())
  1037. }
  1038. func TestLoginAfterUserUpdateEmptyPwd(t *testing.T) {
  1039. usePubKey := false
  1040. user, _, err := httpd.AddUser(getTestUser(usePubKey), http.StatusOK)
  1041. if err != nil {
  1042. t.Errorf("unable to add user: %v", err)
  1043. }
  1044. user.Password = ""
  1045. user.PublicKeys = []string{}
  1046. // password and public key should remain unchanged
  1047. _, _, err = httpd.UpdateUser(user, http.StatusOK)
  1048. if err != nil {
  1049. t.Errorf("unable to update user: %v", err)
  1050. }
  1051. client, err := getSftpClient(user, usePubKey)
  1052. if err != nil {
  1053. t.Errorf("unable to create sftp client: %v", err)
  1054. } else {
  1055. defer client.Close()
  1056. _, err := client.Getwd()
  1057. if err != nil {
  1058. t.Errorf("unable to get working dir: %v", err)
  1059. }
  1060. _, err = client.ReadDir(".")
  1061. if err != nil {
  1062. t.Errorf("unable to read remote dir: %v", err)
  1063. }
  1064. }
  1065. _, err = httpd.RemoveUser(user, http.StatusOK)
  1066. if err != nil {
  1067. t.Errorf("unable to remove user: %v", err)
  1068. }
  1069. os.RemoveAll(user.GetHomeDir())
  1070. }
  1071. func TestLoginAfterUserUpdateEmptyPubKey(t *testing.T) {
  1072. usePubKey := true
  1073. user, _, err := httpd.AddUser(getTestUser(usePubKey), http.StatusOK)
  1074. if err != nil {
  1075. t.Errorf("unable to add user: %v", err)
  1076. }
  1077. user.Password = ""
  1078. user.PublicKeys = []string{}
  1079. // password and public key should remain unchanged
  1080. _, _, err = httpd.UpdateUser(user, http.StatusOK)
  1081. if err != nil {
  1082. t.Errorf("unable to update user: %v", err)
  1083. }
  1084. client, err := getSftpClient(user, usePubKey)
  1085. if err != nil {
  1086. t.Errorf("unable to create sftp client: %v", err)
  1087. } else {
  1088. defer client.Close()
  1089. _, err := client.Getwd()
  1090. if err != nil {
  1091. t.Errorf("unable to get working dir: %v", err)
  1092. }
  1093. _, err = client.ReadDir(".")
  1094. if err != nil {
  1095. t.Errorf("unable to read remote dir: %v", err)
  1096. }
  1097. }
  1098. _, err = httpd.RemoveUser(user, http.StatusOK)
  1099. if err != nil {
  1100. t.Errorf("unable to remove user: %v", err)
  1101. }
  1102. os.RemoveAll(user.GetHomeDir())
  1103. }
  1104. func TestMaxSessions(t *testing.T) {
  1105. usePubKey := false
  1106. u := getTestUser(usePubKey)
  1107. u.MaxSessions = 1
  1108. user, _, err := httpd.AddUser(u, http.StatusOK)
  1109. if err != nil {
  1110. t.Errorf("unable to add user: %v", err)
  1111. }
  1112. client, err := getSftpClient(user, usePubKey)
  1113. if err != nil {
  1114. t.Errorf("unable to create sftp client: %v", err)
  1115. } else {
  1116. defer client.Close()
  1117. _, err := client.Getwd()
  1118. if err != nil {
  1119. t.Errorf("unable to get working dir: %v", err)
  1120. }
  1121. _, err = client.ReadDir(".")
  1122. if err != nil {
  1123. t.Errorf("unable to read remote dir: %v", err)
  1124. }
  1125. _, err = getSftpClient(user, usePubKey)
  1126. if err == nil {
  1127. t.Errorf("max sessions exceeded, new login should not succeed")
  1128. }
  1129. }
  1130. _, err = httpd.RemoveUser(user, http.StatusOK)
  1131. if err != nil {
  1132. t.Errorf("unable to remove user: %v", err)
  1133. }
  1134. os.RemoveAll(user.GetHomeDir())
  1135. }
  1136. func TestQuotaFileReplace(t *testing.T) {
  1137. usePubKey := false
  1138. u := getTestUser(usePubKey)
  1139. u.QuotaFiles = 1000
  1140. user, _, err := httpd.AddUser(u, http.StatusOK)
  1141. if err != nil {
  1142. t.Errorf("unable to add user: %v", err)
  1143. }
  1144. os.RemoveAll(user.GetHomeDir())
  1145. testFileSize := int64(65535)
  1146. testFileName := "test_file.dat"
  1147. testFilePath := filepath.Join(homeBasePath, testFileName)
  1148. client, err := getSftpClient(user, usePubKey)
  1149. if err != nil {
  1150. t.Errorf("unable to create sftp client: %v", err)
  1151. } else {
  1152. defer client.Close()
  1153. expectedQuotaSize := user.UsedQuotaSize + testFileSize
  1154. expectedQuotaFiles := user.UsedQuotaFiles + 1
  1155. err = createTestFile(testFilePath, testFileSize)
  1156. if err != nil {
  1157. t.Errorf("unable to create test file: %v", err)
  1158. }
  1159. err = sftpUploadFile(testFilePath, testFileName, testFileSize, client)
  1160. if err != nil {
  1161. t.Errorf("file upload error: %v", err)
  1162. }
  1163. user, _, err = httpd.GetUserByID(user.ID, http.StatusOK)
  1164. if err != nil {
  1165. t.Errorf("error getting user: %v", err)
  1166. }
  1167. // now replace the same file, the quota must not change
  1168. err = sftpUploadFile(testFilePath, testFileName, testFileSize, client)
  1169. if err != nil {
  1170. t.Errorf("file upload error: %v", err)
  1171. }
  1172. user, _, err = httpd.GetUserByID(user.ID, http.StatusOK)
  1173. if err != nil {
  1174. t.Errorf("error getting user: %v", err)
  1175. }
  1176. if expectedQuotaFiles != user.UsedQuotaFiles {
  1177. t.Errorf("quota files does not match, expected: %v, actual: %v", expectedQuotaFiles, user.UsedQuotaFiles)
  1178. }
  1179. if expectedQuotaSize != user.UsedQuotaSize {
  1180. t.Errorf("quota size does not match, expected: %v, actual: %v", expectedQuotaSize, user.UsedQuotaSize)
  1181. }
  1182. }
  1183. // now set a quota size restriction and upload the same file, upload should fail for space limit exceeded
  1184. user.QuotaSize = testFileSize - 1
  1185. user, _, err = httpd.UpdateUser(user, http.StatusOK)
  1186. if err != nil {
  1187. t.Errorf("error updating user: %v", err)
  1188. }
  1189. client, err = getSftpClient(user, usePubKey)
  1190. if err != nil {
  1191. t.Errorf("unable to create sftp client: %v", err)
  1192. } else {
  1193. err = sftpUploadFile(testFilePath, testFileName, testFileSize, client)
  1194. if err == nil {
  1195. t.Errorf("quota size exceeded, file upload must fail")
  1196. }
  1197. err = client.Remove(testFileName)
  1198. if err != nil {
  1199. t.Errorf("error removing uploaded file: %v", err)
  1200. }
  1201. }
  1202. _, err = httpd.RemoveUser(user, http.StatusOK)
  1203. if err != nil {
  1204. t.Errorf("unable to remove user: %v", err)
  1205. }
  1206. os.Remove(testFilePath)
  1207. os.RemoveAll(user.GetHomeDir())
  1208. }
  1209. func TestQuotaScan(t *testing.T) {
  1210. usePubKey := false
  1211. user, _, err := httpd.AddUser(getTestUser(usePubKey), http.StatusOK)
  1212. if err != nil {
  1213. t.Errorf("unable to add user: %v", err)
  1214. }
  1215. testFileSize := int64(65535)
  1216. expectedQuotaSize := user.UsedQuotaSize + testFileSize
  1217. expectedQuotaFiles := user.UsedQuotaFiles + 1
  1218. client, err := getSftpClient(user, usePubKey)
  1219. if err != nil {
  1220. t.Errorf("unable to create sftp client: %v", err)
  1221. } else {
  1222. defer client.Close()
  1223. testFileName := "test_file.dat"
  1224. testFilePath := filepath.Join(homeBasePath, testFileName)
  1225. err = createTestFile(testFilePath, testFileSize)
  1226. if err != nil {
  1227. t.Errorf("unable to create test file: %v", err)
  1228. }
  1229. err = sftpUploadFile(testFilePath, testFileName, testFileSize, client)
  1230. if err != nil {
  1231. t.Errorf("file upload error: %v", err)
  1232. }
  1233. os.Remove(testFilePath)
  1234. }
  1235. _, err = httpd.RemoveUser(user, http.StatusOK)
  1236. if err != nil {
  1237. t.Errorf("unable to remove user: %v", err)
  1238. }
  1239. // create user with the same home dir, so there is at least an untracked file
  1240. user, _, err = httpd.AddUser(getTestUser(usePubKey), http.StatusOK)
  1241. if err != nil {
  1242. t.Errorf("unable to add user: %v", err)
  1243. }
  1244. _, err = httpd.StartQuotaScan(user, http.StatusCreated)
  1245. if err != nil {
  1246. t.Errorf("error starting quota scan: %v", err)
  1247. }
  1248. err = waitQuotaScans()
  1249. if err != nil {
  1250. t.Errorf("error waiting for active quota scans: %v", err)
  1251. }
  1252. user, _, err = httpd.GetUserByID(user.ID, http.StatusOK)
  1253. if err != nil {
  1254. t.Errorf("error getting user: %v", err)
  1255. }
  1256. if expectedQuotaFiles != user.UsedQuotaFiles {
  1257. t.Errorf("quota files does not match after scan, expected: %v, actual: %v", expectedQuotaFiles, user.UsedQuotaFiles)
  1258. }
  1259. if expectedQuotaSize != user.UsedQuotaSize {
  1260. t.Errorf("quota size does not match after scan, expected: %v, actual: %v", expectedQuotaSize, user.UsedQuotaSize)
  1261. }
  1262. _, err = httpd.RemoveUser(user, http.StatusOK)
  1263. if err != nil {
  1264. t.Errorf("unable to remove user: %v", err)
  1265. }
  1266. os.RemoveAll(user.GetHomeDir())
  1267. }
  1268. func TestMultipleQuotaScans(t *testing.T) {
  1269. if !sftpd.AddQuotaScan(defaultUsername) {
  1270. t.Errorf("add quota failed")
  1271. }
  1272. if sftpd.AddQuotaScan(defaultUsername) {
  1273. t.Errorf("add quota must fail if another scan is already active")
  1274. }
  1275. sftpd.RemoveQuotaScan(defaultUsername)
  1276. activeScans := sftpd.GetQuotaScans()
  1277. if len(activeScans) > 0 {
  1278. t.Errorf("no quota scan must be active: %v", len(activeScans))
  1279. }
  1280. }
  1281. func TestQuotaSize(t *testing.T) {
  1282. usePubKey := false
  1283. testFileSize := int64(65535)
  1284. u := getTestUser(usePubKey)
  1285. u.QuotaFiles = 1
  1286. u.QuotaSize = testFileSize - 1
  1287. user, _, err := httpd.AddUser(u, http.StatusOK)
  1288. if err != nil {
  1289. t.Errorf("unable to add user: %v", err)
  1290. }
  1291. client, err := getSftpClient(user, usePubKey)
  1292. if err != nil {
  1293. t.Errorf("unable to create sftp client: %v", err)
  1294. } else {
  1295. defer client.Close()
  1296. testFileName := "test_file.dat"
  1297. testFilePath := filepath.Join(homeBasePath, testFileName)
  1298. err = createTestFile(testFilePath, testFileSize)
  1299. if err != nil {
  1300. t.Errorf("unable to create test file: %v", err)
  1301. }
  1302. err = sftpUploadFile(testFilePath, testFileName+".quota", testFileSize, client)
  1303. if err != nil {
  1304. t.Errorf("file upload error: %v", err)
  1305. }
  1306. err = sftpUploadFile(testFilePath, testFileName+".quota.1", testFileSize, client)
  1307. if err == nil {
  1308. t.Errorf("user is over quota file upload must fail")
  1309. }
  1310. err = client.Remove(testFileName + ".quota")
  1311. if err != nil {
  1312. t.Errorf("error removing uploaded file: %v", err)
  1313. }
  1314. os.Remove(testFilePath)
  1315. }
  1316. _, err = httpd.RemoveUser(user, http.StatusOK)
  1317. if err != nil {
  1318. t.Errorf("unable to remove user: %v", err)
  1319. }
  1320. os.RemoveAll(user.GetHomeDir())
  1321. }
  1322. func TestBandwidthAndConnections(t *testing.T) {
  1323. usePubKey := false
  1324. testFileSize := int64(131072)
  1325. u := getTestUser(usePubKey)
  1326. u.UploadBandwidth = 30
  1327. u.DownloadBandwidth = 25
  1328. wantedUploadElapsed := 1000 * (testFileSize / 1000) / u.UploadBandwidth
  1329. wantedDownloadElapsed := 1000 * (testFileSize / 1000) / u.DownloadBandwidth
  1330. // 100 ms tolerance
  1331. wantedUploadElapsed -= 100
  1332. wantedDownloadElapsed -= 100
  1333. user, _, err := httpd.AddUser(u, http.StatusOK)
  1334. if err != nil {
  1335. t.Errorf("unable to add user: %v", err)
  1336. }
  1337. client, err := getSftpClient(user, usePubKey)
  1338. if err != nil {
  1339. t.Errorf("unable to create sftp client: %v", err)
  1340. } else {
  1341. defer client.Close()
  1342. testFileName := "test_file.dat"
  1343. testFilePath := filepath.Join(homeBasePath, testFileName)
  1344. err = createTestFile(testFilePath, testFileSize)
  1345. if err != nil {
  1346. t.Errorf("unable to create test file: %v", err)
  1347. }
  1348. startTime := time.Now()
  1349. err = sftpUploadFile(testFilePath, testFileName, testFileSize, client)
  1350. if err != nil {
  1351. t.Errorf("file upload error: %v", err)
  1352. }
  1353. elapsed := time.Since(startTime).Nanoseconds() / 1000000
  1354. if elapsed < (wantedUploadElapsed) {
  1355. t.Errorf("upload bandwidth throttling not respected, elapsed: %v, wanted: %v", elapsed, wantedUploadElapsed)
  1356. }
  1357. startTime = time.Now()
  1358. localDownloadPath := filepath.Join(homeBasePath, "test_download.dat")
  1359. c := sftpDownloadNonBlocking(testFileName, localDownloadPath, testFileSize, client)
  1360. waitForActiveTransfer()
  1361. // wait some additional arbitrary time to wait for transfer activity to happen
  1362. // it is need to reach all the code in CheckIdleConnections
  1363. time.Sleep(100 * time.Millisecond)
  1364. sftpd.CheckIdleConnections()
  1365. err = <-c
  1366. if err != nil {
  1367. t.Errorf("file download error: %v", err)
  1368. }
  1369. elapsed = time.Since(startTime).Nanoseconds() / 1000000
  1370. if elapsed < (wantedDownloadElapsed) {
  1371. t.Errorf("download bandwidth throttling not respected, elapsed: %v, wanted: %v", elapsed, wantedDownloadElapsed)
  1372. }
  1373. // test disconnection
  1374. c = sftpUploadNonBlocking(testFilePath, testFileName+"_partial", testFileSize, client)
  1375. waitForActiveTransfer()
  1376. time.Sleep(100 * time.Millisecond)
  1377. sftpd.CheckIdleConnections()
  1378. stats := sftpd.GetConnectionsStats()
  1379. for _, stat := range stats {
  1380. sftpd.CloseActiveConnection(stat.ConnectionID)
  1381. }
  1382. err = <-c
  1383. if err == nil {
  1384. t.Errorf("connection closed upload must fail")
  1385. }
  1386. os.Remove(testFilePath)
  1387. os.Remove(localDownloadPath)
  1388. }
  1389. _, err = httpd.RemoveUser(user, http.StatusOK)
  1390. if err != nil {
  1391. t.Errorf("unable to remove user: %v", err)
  1392. }
  1393. os.RemoveAll(user.GetHomeDir())
  1394. }
  1395. func TestMissingFile(t *testing.T) {
  1396. usePubKey := false
  1397. u := getTestUser(usePubKey)
  1398. user, _, err := httpd.AddUser(u, http.StatusOK)
  1399. if err != nil {
  1400. t.Errorf("unable to add user: %v", err)
  1401. }
  1402. client, err := getSftpClient(user, usePubKey)
  1403. if err != nil {
  1404. t.Errorf("unable to create sftp client: %v", err)
  1405. } else {
  1406. defer client.Close()
  1407. localDownloadPath := filepath.Join(homeBasePath, "test_download.dat")
  1408. err = sftpDownloadFile("missing_file", localDownloadPath, 0, client)
  1409. if err == nil {
  1410. t.Errorf("download missing file must fail")
  1411. }
  1412. os.Remove(localDownloadPath)
  1413. }
  1414. _, err = httpd.RemoveUser(user, http.StatusOK)
  1415. if err != nil {
  1416. t.Errorf("unable to remove user: %v", err)
  1417. }
  1418. os.RemoveAll(user.GetHomeDir())
  1419. }
  1420. func TestOpenError(t *testing.T) {
  1421. if runtime.GOOS == "windows" {
  1422. t.Skip("this test is not available on Windows")
  1423. }
  1424. usePubKey := false
  1425. u := getTestUser(usePubKey)
  1426. user, _, err := httpd.AddUser(u, http.StatusOK)
  1427. if err != nil {
  1428. t.Errorf("unable to add user: %v", err)
  1429. }
  1430. os.RemoveAll(user.GetHomeDir())
  1431. client, err := getSftpClient(user, usePubKey)
  1432. if err != nil {
  1433. t.Errorf("unable to create sftp client: %v", err)
  1434. } else {
  1435. defer client.Close()
  1436. os.Chmod(user.GetHomeDir(), 0001)
  1437. _, err = client.ReadDir(".")
  1438. if err == nil {
  1439. t.Errorf("read dir must fail if we have no filesystem read permissions")
  1440. }
  1441. os.Chmod(user.GetHomeDir(), 0755)
  1442. testFileSize := int64(65535)
  1443. testFileName := "test_file.dat"
  1444. testFilePath := filepath.Join(user.GetHomeDir(), testFileName)
  1445. err = createTestFile(testFilePath, testFileSize)
  1446. if err != nil {
  1447. t.Errorf("unable to create test file: %v", err)
  1448. }
  1449. _, err = client.Stat(testFileName)
  1450. if err != nil {
  1451. t.Errorf("file stat error: %v", err)
  1452. }
  1453. localDownloadPath := filepath.Join(homeBasePath, "test_download.dat")
  1454. err = sftpDownloadFile(testFileName, localDownloadPath, testFileSize, client)
  1455. if err != nil {
  1456. t.Errorf("file download error: %v", err)
  1457. }
  1458. os.Chmod(testFilePath, 0001)
  1459. err = sftpDownloadFile(testFileName, localDownloadPath, testFileSize, client)
  1460. if err == nil {
  1461. t.Errorf("file download must fail if we have no filesystem read permissions")
  1462. }
  1463. err = sftpUploadFile(localDownloadPath, testFileName, testFileSize, client)
  1464. if err == nil {
  1465. t.Errorf("upload must fail if we have no filesystem write permissions")
  1466. }
  1467. err = client.Mkdir("test")
  1468. if err != nil {
  1469. t.Errorf("error making dir: %v", err)
  1470. }
  1471. os.Chmod(user.GetHomeDir(), 0000)
  1472. _, err = client.Lstat(testFileName)
  1473. if err == nil {
  1474. t.Errorf("file stat must fail if we have no filesystem read permissions")
  1475. }
  1476. os.Chmod(user.GetHomeDir(), 0755)
  1477. os.Chmod(filepath.Join(user.GetHomeDir(), "test"), 0000)
  1478. err = client.Rename(testFileName, path.Join("test", testFileName))
  1479. if err == nil || !strings.Contains(err.Error(), sftp.ErrSSHFxPermissionDenied.Error()) {
  1480. t.Errorf("unexpected error: %v expected: %v", err, sftp.ErrSSHFxPermissionDenied)
  1481. }
  1482. os.Chmod(filepath.Join(user.GetHomeDir(), "test"), 0755)
  1483. os.Remove(testFilePath)
  1484. os.Remove(localDownloadPath)
  1485. }
  1486. _, err = httpd.RemoveUser(user, http.StatusOK)
  1487. if err != nil {
  1488. t.Errorf("unable to remove user: %v", err)
  1489. }
  1490. os.RemoveAll(user.GetHomeDir())
  1491. }
  1492. func TestOverwriteDirWithFile(t *testing.T) {
  1493. usePubKey := false
  1494. u := getTestUser(usePubKey)
  1495. user, _, err := httpd.AddUser(u, http.StatusOK)
  1496. if err != nil {
  1497. t.Errorf("unable to add user: %v", err)
  1498. }
  1499. client, err := getSftpClient(user, usePubKey)
  1500. if err != nil {
  1501. t.Errorf("unable to create sftp client: %v", err)
  1502. } else {
  1503. defer client.Close()
  1504. testFileSize := int64(65535)
  1505. testFileName := "test_file.dat"
  1506. testDirName := "test_dir"
  1507. testFilePath := filepath.Join(homeBasePath, testFileName)
  1508. err = createTestFile(testFilePath, testFileSize)
  1509. if err != nil {
  1510. t.Errorf("unable to create test file: %v", err)
  1511. }
  1512. err = client.Mkdir(testDirName)
  1513. if err != nil {
  1514. t.Errorf("mkdir error: %v", err)
  1515. }
  1516. err = sftpUploadFile(testFilePath, testDirName, testFileSize, client)
  1517. if err == nil {
  1518. t.Errorf("copying a file over an existing dir must fail")
  1519. }
  1520. err = sftpUploadFile(testFilePath, testFileName, testFileSize, client)
  1521. if err != nil {
  1522. t.Errorf("file upload error: %v", err)
  1523. }
  1524. err = client.Rename(testFileName, testDirName)
  1525. if err == nil {
  1526. t.Errorf("rename a file over an existing dir must fail")
  1527. }
  1528. err = client.RemoveDirectory(testDirName)
  1529. if err != nil {
  1530. t.Errorf("dir remove error: %v", err)
  1531. }
  1532. err = client.Remove(testFileName)
  1533. if err != nil {
  1534. t.Errorf("error removing uploaded file: %v", err)
  1535. }
  1536. os.Remove(testFilePath)
  1537. }
  1538. _, err = httpd.RemoveUser(user, http.StatusOK)
  1539. if err != nil {
  1540. t.Errorf("unable to remove user: %v", err)
  1541. }
  1542. os.RemoveAll(user.GetHomeDir())
  1543. }
  1544. func TestPasswordsHashPbkdf2Sha1(t *testing.T) {
  1545. pbkdf2Pwd := "$pbkdf2-sha1$150000$DveVjgYUD05R$X6ydQZdyMeOvpgND2nqGR/0GGic="
  1546. pbkdf2ClearPwd := "password"
  1547. usePubKey := false
  1548. u := getTestUser(usePubKey)
  1549. u.Password = pbkdf2Pwd
  1550. user, _, err := httpd.AddUser(u, http.StatusOK)
  1551. if err != nil {
  1552. t.Errorf("unable to add user: %v", err)
  1553. }
  1554. user.Password = pbkdf2ClearPwd
  1555. client, err := getSftpClient(user, usePubKey)
  1556. if err != nil {
  1557. t.Errorf("unable to login with pkkdf2 sha1 password: %v", err)
  1558. } else {
  1559. defer client.Close()
  1560. _, err = client.Getwd()
  1561. if err != nil {
  1562. t.Errorf("unable to get working dir with pkkdf2 sha1 password: %v", err)
  1563. }
  1564. }
  1565. user.Password = pbkdf2Pwd
  1566. _, err = getSftpClient(user, usePubKey)
  1567. if err == nil {
  1568. t.Errorf("login with wrong password must fail")
  1569. }
  1570. _, err = httpd.RemoveUser(user, http.StatusOK)
  1571. if err != nil {
  1572. t.Errorf("unable to remove user: %v", err)
  1573. }
  1574. os.RemoveAll(user.GetHomeDir())
  1575. }
  1576. func TestPasswordsHashPbkdf2Sha256(t *testing.T) {
  1577. pbkdf2Pwd := "$pbkdf2-sha256$150000$E86a9YMX3zC7$R5J62hsSq+pYw00hLLPKBbcGXmq7fj5+/M0IFoYtZbo="
  1578. pbkdf2ClearPwd := "password"
  1579. usePubKey := false
  1580. u := getTestUser(usePubKey)
  1581. u.Password = pbkdf2Pwd
  1582. user, _, err := httpd.AddUser(u, http.StatusOK)
  1583. if err != nil {
  1584. t.Errorf("unable to add user: %v", err)
  1585. }
  1586. user.Password = pbkdf2ClearPwd
  1587. client, err := getSftpClient(user, usePubKey)
  1588. if err != nil {
  1589. t.Errorf("unable to login with pkkdf2 sha1 password: %v", err)
  1590. } else {
  1591. defer client.Close()
  1592. _, err = client.Getwd()
  1593. if err != nil {
  1594. t.Errorf("unable to get working dir with pkkdf2 sha1 password: %v", err)
  1595. }
  1596. }
  1597. user.Password = pbkdf2Pwd
  1598. _, err = getSftpClient(user, usePubKey)
  1599. if err == nil {
  1600. t.Errorf("login with wrong password must fail")
  1601. }
  1602. _, err = httpd.RemoveUser(user, http.StatusOK)
  1603. if err != nil {
  1604. t.Errorf("unable to remove user: %v", err)
  1605. }
  1606. os.RemoveAll(user.GetHomeDir())
  1607. }
  1608. func TestPasswordsHashPbkdf2Sha512(t *testing.T) {
  1609. pbkdf2Pwd := "$pbkdf2-sha512$150000$dsu7T5R3IaVQ$1hFXPO1ntRBcoWkSLKw+s4sAP09Xtu4Ya7CyxFq64jM9zdUg8eRJVr3NcR2vQgb0W9HHvZaILHsL4Q/Vr6arCg=="
  1610. pbkdf2ClearPwd := "password"
  1611. usePubKey := false
  1612. u := getTestUser(usePubKey)
  1613. u.Password = pbkdf2Pwd
  1614. user, _, err := httpd.AddUser(u, http.StatusOK)
  1615. if err != nil {
  1616. t.Errorf("unable to add user: %v", err)
  1617. }
  1618. user.Password = pbkdf2ClearPwd
  1619. client, err := getSftpClient(user, usePubKey)
  1620. if err != nil {
  1621. t.Errorf("unable to login with pkkdf2 sha1 password: %v", err)
  1622. } else {
  1623. defer client.Close()
  1624. _, err = client.Getwd()
  1625. if err != nil {
  1626. t.Errorf("unable to get working dir with pkkdf2 sha1 password: %v", err)
  1627. }
  1628. }
  1629. user.Password = pbkdf2Pwd
  1630. _, err = getSftpClient(user, usePubKey)
  1631. if err == nil {
  1632. t.Errorf("login with wrong password must fail")
  1633. }
  1634. _, err = httpd.RemoveUser(user, http.StatusOK)
  1635. if err != nil {
  1636. t.Errorf("unable to remove user: %v", err)
  1637. }
  1638. os.RemoveAll(user.GetHomeDir())
  1639. }
  1640. func TestPasswordsHashBcrypt(t *testing.T) {
  1641. bcryptPwd := "$2a$14$ajq8Q7fbtFRQvXpdCq7Jcuy.Rx1h/L4J60Otx.gyNLbAYctGMJ9tK"
  1642. bcryptClearPwd := "secret"
  1643. usePubKey := false
  1644. u := getTestUser(usePubKey)
  1645. u.Password = bcryptPwd
  1646. user, _, err := httpd.AddUser(u, http.StatusOK)
  1647. if err != nil {
  1648. t.Errorf("unable to add user: %v", err)
  1649. }
  1650. user.Password = bcryptClearPwd
  1651. client, err := getSftpClient(user, usePubKey)
  1652. if err != nil {
  1653. t.Errorf("unable to login with bcrypt password: %v", err)
  1654. } else {
  1655. defer client.Close()
  1656. _, err = client.Getwd()
  1657. if err != nil {
  1658. t.Errorf("unable to get working dir with bcrypt password: %v", err)
  1659. }
  1660. }
  1661. user.Password = bcryptPwd
  1662. _, err = getSftpClient(user, usePubKey)
  1663. if err == nil {
  1664. t.Errorf("login with wrong password must fail")
  1665. }
  1666. _, err = httpd.RemoveUser(user, http.StatusOK)
  1667. if err != nil {
  1668. t.Errorf("unable to remove user: %v", err)
  1669. }
  1670. os.RemoveAll(user.GetHomeDir())
  1671. }
  1672. func TestPasswordsHashSHA512Crypt(t *testing.T) {
  1673. sha512CryptPwd := "$6$459ead56b72e44bc$uog86fUxscjt28BZxqFBE2pp2QD8P/1e98MNF75Z9xJfQvOckZnQ/1YJqiq1XeytPuDieHZvDAMoP7352ELkO1"
  1674. clearPwd := "secret"
  1675. usePubKey := false
  1676. u := getTestUser(usePubKey)
  1677. u.Password = sha512CryptPwd
  1678. user, _, err := httpd.AddUser(u, http.StatusOK)
  1679. if err != nil {
  1680. t.Errorf("unable to add user: %v", err)
  1681. }
  1682. user.Password = clearPwd
  1683. client, err := getSftpClient(user, usePubKey)
  1684. if err != nil {
  1685. t.Errorf("unable to login with sha512 crypt password: %v", err)
  1686. } else {
  1687. defer client.Close()
  1688. _, err = client.Getwd()
  1689. if err != nil {
  1690. t.Errorf("unable to get working dir with sha512 crypt password: %v", err)
  1691. }
  1692. }
  1693. user.Password = sha512CryptPwd
  1694. _, err = getSftpClient(user, usePubKey)
  1695. if err == nil {
  1696. t.Errorf("login with wrong password must fail")
  1697. }
  1698. _, err = httpd.RemoveUser(user, http.StatusOK)
  1699. if err != nil {
  1700. t.Errorf("unable to remove user: %v", err)
  1701. }
  1702. os.RemoveAll(user.GetHomeDir())
  1703. }
  1704. func TestPasswordsHashMD5Crypt(t *testing.T) {
  1705. md5CryptPwd := "$1$b5caebda$VODr/nyhGWgZaY8sJ4x05."
  1706. clearPwd := "password"
  1707. usePubKey := false
  1708. u := getTestUser(usePubKey)
  1709. u.Password = md5CryptPwd
  1710. user, _, err := httpd.AddUser(u, http.StatusOK)
  1711. if err != nil {
  1712. t.Errorf("unable to add user: %v", err)
  1713. }
  1714. user.Password = clearPwd
  1715. client, err := getSftpClient(user, usePubKey)
  1716. if err != nil {
  1717. t.Errorf("unable to login with md5 crypt password: %v", err)
  1718. } else {
  1719. defer client.Close()
  1720. _, err = client.Getwd()
  1721. if err != nil {
  1722. t.Errorf("unable to get working dir with md5 crypt password: %v", err)
  1723. }
  1724. }
  1725. user.Password = md5CryptPwd
  1726. _, err = getSftpClient(user, usePubKey)
  1727. if err == nil {
  1728. t.Errorf("login with wrong password must fail")
  1729. }
  1730. _, err = httpd.RemoveUser(user, http.StatusOK)
  1731. if err != nil {
  1732. t.Errorf("unable to remove user: %v", err)
  1733. }
  1734. os.RemoveAll(user.GetHomeDir())
  1735. }
  1736. func TestPermList(t *testing.T) {
  1737. usePubKey := true
  1738. u := getTestUser(usePubKey)
  1739. u.Permissions["/"] = []string{dataprovider.PermDownload, dataprovider.PermUpload, dataprovider.PermDelete, dataprovider.PermRename,
  1740. dataprovider.PermCreateDirs, dataprovider.PermCreateSymlinks, dataprovider.PermOverwrite, dataprovider.PermChmod,
  1741. dataprovider.PermChown, dataprovider.PermChtimes}
  1742. user, _, err := httpd.AddUser(u, http.StatusOK)
  1743. if err != nil {
  1744. t.Errorf("unable to add user: %v", err)
  1745. }
  1746. client, err := getSftpClient(user, usePubKey)
  1747. if err != nil {
  1748. t.Errorf("unable to create sftp client: %v", err)
  1749. } else {
  1750. defer client.Close()
  1751. _, err = client.ReadDir(".")
  1752. if err == nil {
  1753. t.Errorf("read remote dir without permission should not succeed")
  1754. }
  1755. _, err = client.Stat("test_file")
  1756. if err == nil {
  1757. t.Errorf("stat remote file without permission should not succeed")
  1758. }
  1759. }
  1760. _, err = httpd.RemoveUser(user, http.StatusOK)
  1761. if err != nil {
  1762. t.Errorf("unable to remove user: %v", err)
  1763. }
  1764. os.RemoveAll(user.GetHomeDir())
  1765. }
  1766. func TestPermDownload(t *testing.T) {
  1767. usePubKey := true
  1768. u := getTestUser(usePubKey)
  1769. u.Permissions["/"] = []string{dataprovider.PermListItems, dataprovider.PermUpload, dataprovider.PermDelete, dataprovider.PermRename,
  1770. dataprovider.PermCreateDirs, dataprovider.PermCreateSymlinks, dataprovider.PermOverwrite, dataprovider.PermChmod,
  1771. dataprovider.PermChown, dataprovider.PermChtimes}
  1772. user, _, err := httpd.AddUser(u, http.StatusOK)
  1773. if err != nil {
  1774. t.Errorf("unable to add user: %v", err)
  1775. }
  1776. client, err := getSftpClient(user, usePubKey)
  1777. if err != nil {
  1778. t.Errorf("unable to create sftp client: %v", err)
  1779. } else {
  1780. defer client.Close()
  1781. testFileName := "test_file.dat"
  1782. testFilePath := filepath.Join(homeBasePath, testFileName)
  1783. testFileSize := int64(65535)
  1784. err = createTestFile(testFilePath, testFileSize)
  1785. if err != nil {
  1786. t.Errorf("unable to create test file: %v", err)
  1787. }
  1788. err = sftpUploadFile(testFilePath, testFileName, testFileSize, client)
  1789. if err != nil {
  1790. t.Errorf("file upload error: %v", err)
  1791. }
  1792. localDownloadPath := filepath.Join(homeBasePath, "test_download.dat")
  1793. err = sftpDownloadFile(testFileName, localDownloadPath, testFileSize, client)
  1794. if err == nil {
  1795. t.Errorf("file download without permission should not succeed")
  1796. }
  1797. err = client.Remove(testFileName)
  1798. if err != nil {
  1799. t.Errorf("error removing uploaded file: %v", err)
  1800. }
  1801. os.Remove(testFilePath)
  1802. os.Remove(localDownloadPath)
  1803. }
  1804. _, err = httpd.RemoveUser(user, http.StatusOK)
  1805. if err != nil {
  1806. t.Errorf("unable to remove user: %v", err)
  1807. }
  1808. os.RemoveAll(user.GetHomeDir())
  1809. }
  1810. func TestPermUpload(t *testing.T) {
  1811. usePubKey := false
  1812. u := getTestUser(usePubKey)
  1813. u.Permissions["/"] = []string{dataprovider.PermListItems, dataprovider.PermDownload, dataprovider.PermDelete, dataprovider.PermRename,
  1814. dataprovider.PermCreateDirs, dataprovider.PermCreateSymlinks, dataprovider.PermOverwrite, dataprovider.PermChmod,
  1815. dataprovider.PermChown, dataprovider.PermChtimes}
  1816. user, _, err := httpd.AddUser(u, http.StatusOK)
  1817. if err != nil {
  1818. t.Errorf("unable to add user: %v", err)
  1819. }
  1820. client, err := getSftpClient(user, usePubKey)
  1821. if err != nil {
  1822. t.Errorf("unable to create sftp client: %v", err)
  1823. } else {
  1824. defer client.Close()
  1825. testFileName := "test_file.dat"
  1826. testFilePath := filepath.Join(homeBasePath, testFileName)
  1827. testFileSize := int64(65535)
  1828. err = createTestFile(testFilePath, testFileSize)
  1829. if err != nil {
  1830. t.Errorf("unable to create test file: %v", err)
  1831. }
  1832. err = sftpUploadFile(testFilePath, testFileName, testFileSize, client)
  1833. if err == nil {
  1834. t.Errorf("file upload without permission should not succeed")
  1835. }
  1836. os.Remove(testFilePath)
  1837. }
  1838. _, err = httpd.RemoveUser(user, http.StatusOK)
  1839. if err != nil {
  1840. t.Errorf("unable to remove user: %v", err)
  1841. }
  1842. os.RemoveAll(user.GetHomeDir())
  1843. }
  1844. func TestPermOverwrite(t *testing.T) {
  1845. usePubKey := false
  1846. u := getTestUser(usePubKey)
  1847. u.Permissions["/"] = []string{dataprovider.PermListItems, dataprovider.PermDownload, dataprovider.PermUpload, dataprovider.PermDelete,
  1848. dataprovider.PermRename, dataprovider.PermCreateDirs, dataprovider.PermCreateSymlinks, dataprovider.PermChmod,
  1849. dataprovider.PermChown, dataprovider.PermChtimes}
  1850. user, _, err := httpd.AddUser(u, http.StatusOK)
  1851. if err != nil {
  1852. t.Errorf("unable to add user: %v", err)
  1853. }
  1854. client, err := getSftpClient(user, usePubKey)
  1855. if err != nil {
  1856. t.Errorf("unable to create sftp client: %v", err)
  1857. } else {
  1858. defer client.Close()
  1859. testFileName := "test_file.dat"
  1860. testFilePath := filepath.Join(homeBasePath, testFileName)
  1861. testFileSize := int64(65535)
  1862. err = createTestFile(testFilePath, testFileSize)
  1863. if err != nil {
  1864. t.Errorf("unable to create test file: %v", err)
  1865. }
  1866. err = sftpUploadFile(testFilePath, testFileName, testFileSize, client)
  1867. if err != nil {
  1868. t.Errorf("error uploading file: %v", err)
  1869. }
  1870. err = sftpUploadFile(testFilePath, testFileName, testFileSize, client)
  1871. if err == nil {
  1872. t.Errorf("file overwrite without permission should not succeed")
  1873. }
  1874. os.Remove(testFilePath)
  1875. }
  1876. _, err = httpd.RemoveUser(user, http.StatusOK)
  1877. if err != nil {
  1878. t.Errorf("unable to remove user: %v", err)
  1879. }
  1880. os.RemoveAll(user.GetHomeDir())
  1881. }
  1882. func TestPermDelete(t *testing.T) {
  1883. usePubKey := false
  1884. u := getTestUser(usePubKey)
  1885. u.Permissions["/"] = []string{dataprovider.PermListItems, dataprovider.PermDownload, dataprovider.PermUpload, dataprovider.PermRename,
  1886. dataprovider.PermCreateDirs, dataprovider.PermCreateSymlinks, dataprovider.PermOverwrite, dataprovider.PermChmod,
  1887. dataprovider.PermChown, dataprovider.PermChtimes}
  1888. user, _, err := httpd.AddUser(u, http.StatusOK)
  1889. if err != nil {
  1890. t.Errorf("unable to add user: %v", err)
  1891. }
  1892. client, err := getSftpClient(user, usePubKey)
  1893. if err != nil {
  1894. t.Errorf("unable to create sftp client: %v", err)
  1895. } else {
  1896. defer client.Close()
  1897. testFileName := "test_file.dat"
  1898. testFilePath := filepath.Join(homeBasePath, testFileName)
  1899. testFileSize := int64(65535)
  1900. err = createTestFile(testFilePath, testFileSize)
  1901. if err != nil {
  1902. t.Errorf("unable to create test file: %v", err)
  1903. }
  1904. err = sftpUploadFile(testFilePath, testFileName, testFileSize, client)
  1905. if err != nil {
  1906. t.Errorf("file upload error: %v", err)
  1907. }
  1908. err = client.Remove(testFileName)
  1909. if err == nil {
  1910. t.Errorf("delete without permission should not succeed")
  1911. }
  1912. os.Remove(testFilePath)
  1913. }
  1914. _, err = httpd.RemoveUser(user, http.StatusOK)
  1915. if err != nil {
  1916. t.Errorf("unable to remove user: %v", err)
  1917. }
  1918. os.RemoveAll(user.GetHomeDir())
  1919. }
  1920. func TestPermRename(t *testing.T) {
  1921. usePubKey := false
  1922. u := getTestUser(usePubKey)
  1923. u.Permissions["/"] = []string{dataprovider.PermListItems, dataprovider.PermDownload, dataprovider.PermUpload, dataprovider.PermDelete,
  1924. dataprovider.PermCreateDirs, dataprovider.PermCreateSymlinks, dataprovider.PermOverwrite, dataprovider.PermChmod,
  1925. dataprovider.PermChown, dataprovider.PermChtimes}
  1926. user, _, err := httpd.AddUser(u, http.StatusOK)
  1927. if err != nil {
  1928. t.Errorf("unable to add user: %v", err)
  1929. }
  1930. client, err := getSftpClient(user, usePubKey)
  1931. if err != nil {
  1932. t.Errorf("unable to create sftp client: %v", err)
  1933. } else {
  1934. defer client.Close()
  1935. testFileName := "test_file.dat"
  1936. testFilePath := filepath.Join(homeBasePath, testFileName)
  1937. testFileSize := int64(65535)
  1938. err = createTestFile(testFilePath, testFileSize)
  1939. if err != nil {
  1940. t.Errorf("unable to create test file: %v", err)
  1941. }
  1942. err = sftpUploadFile(testFilePath, testFileName, testFileSize, client)
  1943. if err != nil {
  1944. t.Errorf("file upload error: %v", err)
  1945. }
  1946. err = client.Rename(testFileName, testFileName+".rename")
  1947. if err == nil {
  1948. t.Errorf("rename without permission should not succeed")
  1949. }
  1950. err = client.Remove(testFileName)
  1951. if err != nil {
  1952. t.Errorf("error removing uploaded file: %v", err)
  1953. }
  1954. os.Remove(testFilePath)
  1955. }
  1956. _, err = httpd.RemoveUser(user, http.StatusOK)
  1957. if err != nil {
  1958. t.Errorf("unable to remove user: %v", err)
  1959. }
  1960. os.RemoveAll(user.GetHomeDir())
  1961. }
  1962. func TestPermCreateDirs(t *testing.T) {
  1963. usePubKey := false
  1964. u := getTestUser(usePubKey)
  1965. u.Permissions["/"] = []string{dataprovider.PermListItems, dataprovider.PermDownload, dataprovider.PermUpload, dataprovider.PermDelete,
  1966. dataprovider.PermRename, dataprovider.PermCreateSymlinks, dataprovider.PermOverwrite, dataprovider.PermChmod,
  1967. dataprovider.PermChown, dataprovider.PermChtimes}
  1968. user, _, err := httpd.AddUser(u, http.StatusOK)
  1969. if err != nil {
  1970. t.Errorf("unable to add user: %v", err)
  1971. }
  1972. client, err := getSftpClient(user, usePubKey)
  1973. if err != nil {
  1974. t.Errorf("unable to create sftp client: %v", err)
  1975. } else {
  1976. defer client.Close()
  1977. err = client.Mkdir("testdir")
  1978. if err == nil {
  1979. t.Errorf("mkdir without permission should not succeed")
  1980. }
  1981. }
  1982. _, err = httpd.RemoveUser(user, http.StatusOK)
  1983. if err != nil {
  1984. t.Errorf("unable to remove user: %v", err)
  1985. }
  1986. os.RemoveAll(user.GetHomeDir())
  1987. }
  1988. func TestPermSymlink(t *testing.T) {
  1989. usePubKey := false
  1990. u := getTestUser(usePubKey)
  1991. u.Permissions["/"] = []string{dataprovider.PermListItems, dataprovider.PermDownload, dataprovider.PermUpload, dataprovider.PermDelete,
  1992. dataprovider.PermRename, dataprovider.PermCreateDirs, dataprovider.PermOverwrite, dataprovider.PermChmod, dataprovider.PermChown,
  1993. dataprovider.PermChtimes}
  1994. user, _, err := httpd.AddUser(u, http.StatusOK)
  1995. if err != nil {
  1996. t.Errorf("unable to add user: %v", err)
  1997. }
  1998. client, err := getSftpClient(user, usePubKey)
  1999. if err != nil {
  2000. t.Errorf("unable to create sftp client: %v", err)
  2001. } else {
  2002. defer client.Close()
  2003. testFileName := "test_file.dat"
  2004. testFilePath := filepath.Join(homeBasePath, testFileName)
  2005. testFileSize := int64(65535)
  2006. err = createTestFile(testFilePath, testFileSize)
  2007. if err != nil {
  2008. t.Errorf("unable to create test file: %v", err)
  2009. }
  2010. err = sftpUploadFile(testFilePath, testFileName, testFileSize, client)
  2011. if err != nil {
  2012. t.Errorf("file upload error: %v", err)
  2013. }
  2014. err = client.Symlink(testFilePath, testFilePath+".symlink")
  2015. if err == nil {
  2016. t.Errorf("symlink without permission should not succeed")
  2017. }
  2018. err = client.Remove(testFileName)
  2019. if err != nil {
  2020. t.Errorf("error removing uploaded file: %v", err)
  2021. }
  2022. os.Remove(testFilePath)
  2023. }
  2024. _, err = httpd.RemoveUser(user, http.StatusOK)
  2025. if err != nil {
  2026. t.Errorf("unable to remove user: %v", err)
  2027. }
  2028. os.RemoveAll(user.GetHomeDir())
  2029. }
  2030. func TestPermChmod(t *testing.T) {
  2031. usePubKey := false
  2032. u := getTestUser(usePubKey)
  2033. u.Permissions["/"] = []string{dataprovider.PermListItems, dataprovider.PermDownload, dataprovider.PermUpload, dataprovider.PermDelete,
  2034. dataprovider.PermRename, dataprovider.PermCreateDirs, dataprovider.PermCreateSymlinks, dataprovider.PermOverwrite,
  2035. dataprovider.PermChown, dataprovider.PermChtimes}
  2036. user, _, err := httpd.AddUser(u, http.StatusOK)
  2037. if err != nil {
  2038. t.Errorf("unable to add user: %v", err)
  2039. }
  2040. client, err := getSftpClient(user, usePubKey)
  2041. if err != nil {
  2042. t.Errorf("unable to create sftp client: %v", err)
  2043. } else {
  2044. defer client.Close()
  2045. testFileName := "test_file.dat"
  2046. testFilePath := filepath.Join(homeBasePath, testFileName)
  2047. testFileSize := int64(65535)
  2048. err = createTestFile(testFilePath, testFileSize)
  2049. if err != nil {
  2050. t.Errorf("unable to create test file: %v", err)
  2051. }
  2052. err = sftpUploadFile(testFilePath, testFileName, testFileSize, client)
  2053. if err != nil {
  2054. t.Errorf("file upload error: %v", err)
  2055. }
  2056. err = client.Chmod(testFileName, 0666)
  2057. if err == nil {
  2058. t.Errorf("chmod without permission should not succeed")
  2059. }
  2060. err = client.Remove(testFileName)
  2061. if err != nil {
  2062. t.Errorf("error removing uploaded file: %v", err)
  2063. }
  2064. os.Remove(testFilePath)
  2065. }
  2066. _, err = httpd.RemoveUser(user, http.StatusOK)
  2067. if err != nil {
  2068. t.Errorf("unable to remove user: %v", err)
  2069. }
  2070. os.RemoveAll(user.GetHomeDir())
  2071. }
  2072. func TestPermChown(t *testing.T) {
  2073. usePubKey := false
  2074. u := getTestUser(usePubKey)
  2075. u.Permissions["/"] = []string{dataprovider.PermListItems, dataprovider.PermDownload, dataprovider.PermUpload, dataprovider.PermDelete,
  2076. dataprovider.PermRename, dataprovider.PermCreateDirs, dataprovider.PermCreateSymlinks, dataprovider.PermOverwrite,
  2077. dataprovider.PermChmod, dataprovider.PermChtimes}
  2078. user, _, err := httpd.AddUser(u, http.StatusOK)
  2079. if err != nil {
  2080. t.Errorf("unable to add user: %v", err)
  2081. }
  2082. client, err := getSftpClient(user, usePubKey)
  2083. if err != nil {
  2084. t.Errorf("unable to create sftp client: %v", err)
  2085. } else {
  2086. defer client.Close()
  2087. testFileName := "test_file.dat"
  2088. testFilePath := filepath.Join(homeBasePath, testFileName)
  2089. testFileSize := int64(65535)
  2090. err = createTestFile(testFilePath, testFileSize)
  2091. if err != nil {
  2092. t.Errorf("unable to create test file: %v", err)
  2093. }
  2094. err = sftpUploadFile(testFilePath, testFileName, testFileSize, client)
  2095. if err != nil {
  2096. t.Errorf("file upload error: %v", err)
  2097. }
  2098. err = client.Chown(testFileName, os.Getuid(), os.Getgid())
  2099. if err == nil {
  2100. t.Errorf("chown without permission should not succeed")
  2101. }
  2102. err = client.Remove(testFileName)
  2103. if err != nil {
  2104. t.Errorf("error removing uploaded file: %v", err)
  2105. }
  2106. os.Remove(testFilePath)
  2107. }
  2108. _, err = httpd.RemoveUser(user, http.StatusOK)
  2109. if err != nil {
  2110. t.Errorf("unable to remove user: %v", err)
  2111. }
  2112. os.RemoveAll(user.GetHomeDir())
  2113. }
  2114. func TestPermChtimes(t *testing.T) {
  2115. usePubKey := false
  2116. u := getTestUser(usePubKey)
  2117. u.Permissions["/"] = []string{dataprovider.PermListItems, dataprovider.PermDownload, dataprovider.PermUpload, dataprovider.PermDelete,
  2118. dataprovider.PermRename, dataprovider.PermCreateDirs, dataprovider.PermCreateSymlinks, dataprovider.PermOverwrite,
  2119. dataprovider.PermChmod, dataprovider.PermChown}
  2120. user, _, err := httpd.AddUser(u, http.StatusOK)
  2121. if err != nil {
  2122. t.Errorf("unable to add user: %v", err)
  2123. }
  2124. client, err := getSftpClient(user, usePubKey)
  2125. if err != nil {
  2126. t.Errorf("unable to create sftp client: %v", err)
  2127. } else {
  2128. defer client.Close()
  2129. testFileName := "test_file.dat"
  2130. testFilePath := filepath.Join(homeBasePath, testFileName)
  2131. testFileSize := int64(65535)
  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, testFileSize, client)
  2137. if err != nil {
  2138. t.Errorf("file upload error: %v", err)
  2139. }
  2140. err = client.Chtimes(testFileName, time.Now(), time.Now())
  2141. if err == nil {
  2142. t.Errorf("chtimes without permission should not succeed")
  2143. }
  2144. err = client.Remove(testFileName)
  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 TestSubDirsUploads(t *testing.T) {
  2157. usePubKey := true
  2158. u := getTestUser(usePubKey)
  2159. u.Permissions["/"] = []string{dataprovider.PermAny}
  2160. u.Permissions["/subdir"] = []string{dataprovider.PermChtimes, dataprovider.PermDownload}
  2161. user, _, err := httpd.AddUser(u, http.StatusOK)
  2162. if err != nil {
  2163. t.Errorf("unable to add user: %v", err)
  2164. }
  2165. client, err := getSftpClient(user, usePubKey)
  2166. if err != nil {
  2167. t.Errorf("unable to create sftp client: %v", err)
  2168. } else {
  2169. defer client.Close()
  2170. err = client.Mkdir("subdir")
  2171. if err != nil {
  2172. t.Errorf("unexpected mkdir error: %v", err)
  2173. }
  2174. testFileName := "test_file.dat"
  2175. testFileNameSub := "/subdir/test_file_dat"
  2176. testFilePath := filepath.Join(homeBasePath, testFileName)
  2177. testFileSize := int64(65535)
  2178. err = createTestFile(testFilePath, testFileSize)
  2179. if err != nil {
  2180. t.Errorf("unable to create test file: %v", err)
  2181. }
  2182. err = sftpUploadFile(testFilePath, testFileName, testFileSize, client)
  2183. if err != nil {
  2184. t.Errorf("file upload error: %v", err)
  2185. }
  2186. err = sftpUploadFile(testFilePath, testFileNameSub, testFileSize, client)
  2187. if !strings.Contains(err.Error(), "Permission Denied") {
  2188. t.Errorf("unexpected upload error: %v", err)
  2189. }
  2190. err = client.Symlink(testFileName, testFileNameSub+".link")
  2191. if !strings.Contains(err.Error(), "Permission Denied") {
  2192. t.Errorf("unexpected upload error: %v", err)
  2193. }
  2194. err = client.Symlink(testFileName, testFileName+".link")
  2195. if err != nil {
  2196. t.Errorf("symlink error: %v", err)
  2197. }
  2198. err = client.Rename(testFileName, testFileNameSub+".rename")
  2199. if !strings.Contains(err.Error(), "Permission Denied") {
  2200. t.Errorf("unexpected rename error: %v", err)
  2201. }
  2202. err = client.Rename(testFileName, testFileName+".rename")
  2203. if err != nil {
  2204. t.Errorf("rename error: %v", err)
  2205. }
  2206. err = client.Remove(testFileNameSub)
  2207. if !strings.Contains(err.Error(), "Permission Denied") {
  2208. t.Errorf("unexpected upload error: %v", err)
  2209. }
  2210. err = client.Remove(testFileName + ".rename")
  2211. if err != nil {
  2212. t.Errorf("remove error: %v", err)
  2213. }
  2214. os.Remove(testFilePath)
  2215. }
  2216. httpd.RemoveUser(user, http.StatusOK)
  2217. os.RemoveAll(user.GetHomeDir())
  2218. }
  2219. func TestSubDirsOverwrite(t *testing.T) {
  2220. usePubKey := true
  2221. u := getTestUser(usePubKey)
  2222. u.Permissions["/"] = []string{dataprovider.PermAny}
  2223. u.Permissions["/subdir"] = []string{dataprovider.PermOverwrite, dataprovider.PermListItems}
  2224. user, _, err := httpd.AddUser(u, http.StatusOK)
  2225. if err != nil {
  2226. t.Errorf("unable to add user: %v", err)
  2227. }
  2228. client, err := getSftpClient(user, usePubKey)
  2229. if err != nil {
  2230. t.Errorf("unable to create sftp client: %v", err)
  2231. } else {
  2232. defer client.Close()
  2233. testFileName := "/subdir/test_file.dat"
  2234. testFilePath := filepath.Join(homeBasePath, "test_file.dat")
  2235. testFileSFTPPath := filepath.Join(u.GetHomeDir(), "subdir", "test_file.dat")
  2236. testFileSize := int64(65535)
  2237. err = createTestFile(testFilePath, testFileSize)
  2238. if err != nil {
  2239. t.Errorf("unable to create test file: %v", err)
  2240. }
  2241. err = createTestFile(testFileSFTPPath, 16384)
  2242. if err != nil {
  2243. t.Errorf("unable to create test file: %v", err)
  2244. }
  2245. err = sftpUploadFile(testFilePath, testFileName+".new", testFileSize, client)
  2246. if !strings.Contains(err.Error(), "Permission Denied") {
  2247. t.Errorf("unexpected upload error: %v", err)
  2248. }
  2249. err = sftpUploadFile(testFilePath, testFileName, testFileSize, client)
  2250. if err != nil {
  2251. t.Errorf("unexpected overwrite error: %v", err)
  2252. }
  2253. os.Remove(testFilePath)
  2254. }
  2255. httpd.RemoveUser(user, http.StatusOK)
  2256. os.RemoveAll(user.GetHomeDir())
  2257. }
  2258. func TestSubDirsDownloads(t *testing.T) {
  2259. usePubKey := true
  2260. u := getTestUser(usePubKey)
  2261. u.Permissions["/"] = []string{dataprovider.PermAny}
  2262. u.Permissions["/subdir"] = []string{dataprovider.PermChmod, dataprovider.PermUpload, dataprovider.PermListItems}
  2263. user, _, err := httpd.AddUser(u, http.StatusOK)
  2264. if err != nil {
  2265. t.Errorf("unable to add user: %v", err)
  2266. }
  2267. client, err := getSftpClient(user, usePubKey)
  2268. if err != nil {
  2269. t.Errorf("unable to create sftp client: %v", err)
  2270. } else {
  2271. defer client.Close()
  2272. err = client.Mkdir("subdir")
  2273. if err != nil {
  2274. t.Errorf("unexpected mkdir error: %v", err)
  2275. }
  2276. testFileName := "/subdir/test_file.dat"
  2277. testFilePath := filepath.Join(homeBasePath, "test_file.dat")
  2278. testFileSize := int64(65535)
  2279. err = createTestFile(testFilePath, testFileSize)
  2280. if err != nil {
  2281. t.Errorf("unable to create test file: %v", err)
  2282. }
  2283. err = sftpUploadFile(testFilePath, testFileName, testFileSize, client)
  2284. if err != nil {
  2285. t.Errorf("file upload error: %v", err)
  2286. }
  2287. localDownloadPath := filepath.Join(homeBasePath, "test_download.dat")
  2288. err = sftpDownloadFile(testFileName, localDownloadPath, testFileSize, client)
  2289. if !strings.Contains(err.Error(), "Permission Denied") {
  2290. t.Errorf("unexpected upload error: %v", err)
  2291. }
  2292. err = sftpUploadFile(testFilePath, testFileName, testFileSize, client)
  2293. if !strings.Contains(err.Error(), "Permission Denied") {
  2294. t.Errorf("unexpected overwrite error: %v", err)
  2295. }
  2296. err = client.Chtimes(testFileName, time.Now(), time.Now())
  2297. if !strings.Contains(err.Error(), "Permission Denied") {
  2298. t.Errorf("unexpected chtimes error: %v", err)
  2299. }
  2300. err = client.Rename(testFileName, testFileName+".rename")
  2301. if !strings.Contains(err.Error(), "Permission Denied") {
  2302. t.Errorf("unexpected rename error: %v", err)
  2303. }
  2304. err = client.Symlink(testFileName, testFileName+".link")
  2305. if !strings.Contains(err.Error(), "Permission Denied") {
  2306. t.Errorf("unexpected symlink error: %v", err)
  2307. }
  2308. err = client.Remove(testFileName)
  2309. if !strings.Contains(err.Error(), "Permission Denied") {
  2310. t.Errorf("unexpected remove error: %v", err)
  2311. }
  2312. os.Remove(localDownloadPath)
  2313. os.Remove(testFilePath)
  2314. }
  2315. httpd.RemoveUser(user, http.StatusOK)
  2316. os.RemoveAll(user.GetHomeDir())
  2317. }
  2318. func TestPermsSubDirsSetstat(t *testing.T) {
  2319. // for setstat we check the parent dir permission if the requested path is a dir
  2320. // otherwise the path permission
  2321. usePubKey := true
  2322. u := getTestUser(usePubKey)
  2323. u.Permissions["/"] = []string{dataprovider.PermListItems, dataprovider.PermCreateDirs}
  2324. u.Permissions["/subdir"] = []string{dataprovider.PermAny}
  2325. user, _, err := httpd.AddUser(u, http.StatusOK)
  2326. if err != nil {
  2327. t.Errorf("unable to add user: %v", err)
  2328. }
  2329. client, err := getSftpClient(user, usePubKey)
  2330. if err != nil {
  2331. t.Errorf("unable to create sftp client: %v", err)
  2332. } else {
  2333. defer client.Close()
  2334. err = client.Mkdir("subdir")
  2335. if err != nil {
  2336. t.Errorf("unexpected mkdir error: %v", err)
  2337. }
  2338. testFileName := "/subdir/test_file.dat"
  2339. testFilePath := filepath.Join(homeBasePath, "test_file.dat")
  2340. testFileSize := int64(65535)
  2341. err = createTestFile(testFilePath, testFileSize)
  2342. if err != nil {
  2343. t.Errorf("unable to create test file: %v", err)
  2344. }
  2345. err = sftpUploadFile(testFilePath, testFileName, testFileSize, client)
  2346. if err != nil {
  2347. t.Errorf("file upload error: %v", err)
  2348. }
  2349. err = client.Chtimes("/subdir/", time.Now(), time.Now())
  2350. if !strings.Contains(err.Error(), "Permission Denied") {
  2351. t.Errorf("unexpected chtimes error: %v", err)
  2352. }
  2353. err = client.Chtimes("subdir/", time.Now(), time.Now())
  2354. if !strings.Contains(err.Error(), "Permission Denied") {
  2355. t.Errorf("unexpected chtimes error: %v", err)
  2356. }
  2357. err = client.Chtimes(testFileName, time.Now(), time.Now())
  2358. if err != nil {
  2359. t.Errorf("unexpected chtimes error: %v", err)
  2360. }
  2361. os.Remove(testFilePath)
  2362. }
  2363. httpd.RemoveUser(user, http.StatusOK)
  2364. os.RemoveAll(user.GetHomeDir())
  2365. }
  2366. func TestPermsSubDirsCommands(t *testing.T) {
  2367. usePubKey := true
  2368. u := getTestUser(usePubKey)
  2369. u.Permissions["/"] = []string{dataprovider.PermAny}
  2370. u.Permissions["/subdir"] = []string{dataprovider.PermDownload, dataprovider.PermUpload}
  2371. user, _, err := httpd.AddUser(u, http.StatusOK)
  2372. if err != nil {
  2373. t.Errorf("unable to add user: %v", err)
  2374. }
  2375. client, err := getSftpClient(user, usePubKey)
  2376. if err != nil {
  2377. t.Errorf("unable to create sftp client: %v", err)
  2378. } else {
  2379. defer client.Close()
  2380. client.Mkdir("subdir")
  2381. acmodTime := time.Now()
  2382. err = client.Chtimes("/subdir", acmodTime, acmodTime)
  2383. if err != nil {
  2384. t.Errorf("unexpected chtimes error: %v", err)
  2385. }
  2386. _, err = client.Stat("/subdir")
  2387. if err != nil {
  2388. t.Errorf("unexpected stat error: %v", err)
  2389. }
  2390. _, err = client.ReadDir("/")
  2391. if err != nil {
  2392. t.Errorf("unexpected readdir error: %v", err)
  2393. }
  2394. _, err = client.ReadDir("/subdir")
  2395. if !strings.Contains(err.Error(), "Permission Denied") {
  2396. t.Errorf("unexpected error: %v", err)
  2397. }
  2398. err = client.RemoveDirectory("/subdir/dir")
  2399. if !strings.Contains(err.Error(), "Permission Denied") {
  2400. t.Errorf("unexpected error: %v", err)
  2401. }
  2402. err = client.Mkdir("/subdir/dir")
  2403. if !strings.Contains(err.Error(), "Permission Denied") {
  2404. t.Errorf("unexpected error: %v", err)
  2405. }
  2406. client.Mkdir("/otherdir")
  2407. err = client.Rename("/otherdir", "/subdir/otherdir")
  2408. if !strings.Contains(err.Error(), "Permission Denied") {
  2409. t.Errorf("unexpected error: %v", err)
  2410. }
  2411. err = client.Symlink("/otherdir", "/subdir/otherdir")
  2412. if !strings.Contains(err.Error(), "Permission Denied") {
  2413. t.Errorf("unexpected error: %v", err)
  2414. }
  2415. err = client.Symlink("/otherdir", "/otherdir_link")
  2416. if err != nil {
  2417. t.Errorf("unexpected rename dir error: %v", err)
  2418. }
  2419. err = client.Rename("/otherdir", "/otherdir1")
  2420. if err != nil {
  2421. t.Errorf("unexpected rename dir error: %v", err)
  2422. }
  2423. err = client.RemoveDirectory("/subdir")
  2424. if err != nil {
  2425. t.Errorf("unexpected remove dir error: %v", err)
  2426. }
  2427. }
  2428. httpd.RemoveUser(user, http.StatusOK)
  2429. os.RemoveAll(user.GetHomeDir())
  2430. }
  2431. func TestRootDirCommands(t *testing.T) {
  2432. usePubKey := true
  2433. u := getTestUser(usePubKey)
  2434. u.Permissions["/"] = []string{dataprovider.PermAny}
  2435. u.Permissions["/subdir"] = []string{dataprovider.PermDownload, dataprovider.PermUpload}
  2436. user, _, err := httpd.AddUser(u, http.StatusOK)
  2437. if err != nil {
  2438. t.Errorf("unable to add user: %v", err)
  2439. }
  2440. client, err := getSftpClient(user, usePubKey)
  2441. if err != nil {
  2442. t.Errorf("unable to create sftp client: %v", err)
  2443. } else {
  2444. defer client.Close()
  2445. err = client.Rename("/", "rootdir")
  2446. if !strings.Contains(err.Error(), "Permission Denied") {
  2447. t.Errorf("unexpected error renaming root dir: %v", err)
  2448. }
  2449. err = client.Symlink("/", "rootdir")
  2450. if !strings.Contains(err.Error(), "Permission Denied") {
  2451. t.Errorf("unexpected error symlinking root dir: %v", err)
  2452. }
  2453. err = client.RemoveDirectory("/")
  2454. if !strings.Contains(err.Error(), "Permission Denied") {
  2455. t.Errorf("unexpected error removing root dir: %v", err)
  2456. }
  2457. }
  2458. httpd.RemoveUser(user, http.StatusOK)
  2459. os.RemoveAll(user.GetHomeDir())
  2460. }
  2461. func TestRelativePaths(t *testing.T) {
  2462. user := getTestUser(true)
  2463. path := filepath.Join(user.HomeDir, "/")
  2464. rel := user.GetRelativePath(path)
  2465. if rel != "/" {
  2466. t.Errorf("Unexpected relative path: %v", rel)
  2467. }
  2468. path = filepath.Join(user.HomeDir, "//")
  2469. rel = user.GetRelativePath(path)
  2470. if rel != "/" {
  2471. t.Errorf("Unexpected relative path: %v", rel)
  2472. }
  2473. path = filepath.Join(user.HomeDir, "../..")
  2474. rel = user.GetRelativePath(path)
  2475. if rel != "/" {
  2476. t.Errorf("Unexpected relative path: %v", rel)
  2477. }
  2478. path = filepath.Join(user.HomeDir, "../../../../../")
  2479. rel = user.GetRelativePath(path)
  2480. if rel != "/" {
  2481. t.Errorf("Unexpected relative path: %v", rel)
  2482. }
  2483. path = filepath.Join(user.HomeDir, "/..")
  2484. rel = user.GetRelativePath(path)
  2485. if rel != "/" {
  2486. t.Errorf("Unexpected relative path: %v", rel)
  2487. }
  2488. path = filepath.Join(user.HomeDir, "/../../../..")
  2489. rel = user.GetRelativePath(path)
  2490. if rel != "/" {
  2491. t.Errorf("Unexpected relative path: %v", rel)
  2492. }
  2493. path = filepath.Join(user.HomeDir, "")
  2494. rel = user.GetRelativePath(path)
  2495. if rel != "/" {
  2496. t.Errorf("Unexpected relative path: %v", rel)
  2497. }
  2498. path = filepath.Join(user.HomeDir, ".")
  2499. rel = user.GetRelativePath(path)
  2500. if rel != "/" {
  2501. t.Errorf("Unexpected relative path: %v", rel)
  2502. }
  2503. path = filepath.Join(user.HomeDir, "somedir")
  2504. rel = user.GetRelativePath(path)
  2505. if rel != "/somedir" {
  2506. t.Errorf("Unexpected relative path: %v", rel)
  2507. }
  2508. path = filepath.Join(user.HomeDir, "/somedir/subdir")
  2509. rel = user.GetRelativePath(path)
  2510. if rel != "/somedir/subdir" {
  2511. t.Errorf("Unexpected relative path: %v", rel)
  2512. }
  2513. }
  2514. func TestUserPerms(t *testing.T) {
  2515. user := getTestUser(true)
  2516. user.Permissions = make(map[string][]string)
  2517. user.Permissions["/"] = []string{dataprovider.PermListItems}
  2518. user.Permissions["/p"] = []string{dataprovider.PermDelete}
  2519. user.Permissions["/p/1"] = []string{dataprovider.PermDownload, dataprovider.PermUpload}
  2520. user.Permissions["/p/2"] = []string{dataprovider.PermCreateDirs}
  2521. user.Permissions["/p/3"] = []string{dataprovider.PermChmod}
  2522. user.Permissions["/p/3/4"] = []string{dataprovider.PermChtimes}
  2523. user.Permissions["/tmp"] = []string{dataprovider.PermRename}
  2524. if !user.HasPerm(dataprovider.PermListItems, filepath.Join(user.HomeDir, "/")) {
  2525. t.Error("expected permission not found")
  2526. }
  2527. if !user.HasPerm(dataprovider.PermListItems, filepath.Join(user.HomeDir, ".")) {
  2528. t.Error("expected permission not found")
  2529. }
  2530. if !user.HasPerm(dataprovider.PermListItems, filepath.Join(user.HomeDir, "")) {
  2531. t.Error("expected permission not found")
  2532. }
  2533. if !user.HasPerm(dataprovider.PermListItems, filepath.Join(user.HomeDir, "../")) {
  2534. t.Error("expected permission not found")
  2535. }
  2536. // path p and /p are the same
  2537. if !user.HasPerm(dataprovider.PermDelete, filepath.Join(user.HomeDir, "/p")) {
  2538. t.Error("expected permission not found")
  2539. }
  2540. if !user.HasPerm(dataprovider.PermDownload, filepath.Join(user.HomeDir, "/p/1")) {
  2541. t.Error("expected permission not found")
  2542. }
  2543. if !user.HasPerm(dataprovider.PermCreateDirs, filepath.Join(user.HomeDir, "p/2")) {
  2544. t.Error("expected permission not found")
  2545. }
  2546. if !user.HasPerm(dataprovider.PermChmod, filepath.Join(user.HomeDir, "/p/3")) {
  2547. t.Error("expected permission not found")
  2548. }
  2549. if !user.HasPerm(dataprovider.PermChtimes, filepath.Join(user.HomeDir, "p/3/4")) {
  2550. t.Error("expected permission not found")
  2551. }
  2552. if !user.HasPerm(dataprovider.PermChtimes, filepath.Join(user.HomeDir, "p/3/4/../4")) {
  2553. t.Error("expected permission not found")
  2554. }
  2555. // undefined paths have permissions of the nearest path
  2556. if !user.HasPerm(dataprovider.PermListItems, filepath.Join(user.HomeDir, "/p34")) {
  2557. t.Error("expected permission not found")
  2558. }
  2559. if !user.HasPerm(dataprovider.PermListItems, filepath.Join(user.HomeDir, "/p34/p1/file.dat")) {
  2560. t.Error("expected permission not found")
  2561. }
  2562. if !user.HasPerm(dataprovider.PermChtimes, filepath.Join(user.HomeDir, "/p/3/4/5/6")) {
  2563. t.Error("expected permission not found")
  2564. }
  2565. if !user.HasPerm(dataprovider.PermDownload, filepath.Join(user.HomeDir, "/p/1/test/file.dat")) {
  2566. t.Error("expected permission not found")
  2567. }
  2568. }
  2569. func TestUserFiltersIPMaskConditions(t *testing.T) {
  2570. user := getTestUser(true)
  2571. // with no filter login must be allowed even if the remoteIP is invalid
  2572. if !user.IsLoginAllowed("192.168.1.5") {
  2573. t.Error("unexpected login denied")
  2574. }
  2575. if !user.IsLoginAllowed("invalid") {
  2576. t.Error("unexpected login denied")
  2577. }
  2578. user.Filters.DeniedIP = append(user.Filters.DeniedIP, "192.168.1.0/24")
  2579. if user.IsLoginAllowed("192.168.1.5") {
  2580. t.Error("unexpected login allowed")
  2581. }
  2582. if !user.IsLoginAllowed("192.168.2.6") {
  2583. t.Error("unexpected login denied")
  2584. }
  2585. user.Filters.AllowedIP = append(user.Filters.AllowedIP, "192.168.1.5/32")
  2586. // if the same ip/mask is both denied and allowed then login must be denied
  2587. if user.IsLoginAllowed("192.168.1.5") {
  2588. t.Error("unexpected login allowed")
  2589. }
  2590. if user.IsLoginAllowed("192.168.3.6") {
  2591. t.Error("unexpected login allowed")
  2592. }
  2593. user.Filters.DeniedIP = []string{}
  2594. if !user.IsLoginAllowed("192.168.1.5") {
  2595. t.Error("unexpected login denied")
  2596. }
  2597. if user.IsLoginAllowed("192.168.1.6") {
  2598. t.Error("unexpected login allowed")
  2599. }
  2600. user.Filters.DeniedIP = []string{"192.168.0.0/16", "172.16.0.0/16"}
  2601. user.Filters.AllowedIP = []string{}
  2602. if user.IsLoginAllowed("192.168.5.255") {
  2603. t.Error("unexpected login allowed")
  2604. }
  2605. if user.IsLoginAllowed("172.16.1.2") {
  2606. t.Error("unexpected login allowed")
  2607. }
  2608. if !user.IsLoginAllowed("172.18.2.1") {
  2609. t.Error("unexpected login denied")
  2610. }
  2611. user.Filters.AllowedIP = []string{"10.4.4.0/24"}
  2612. if user.IsLoginAllowed("10.5.4.2") {
  2613. t.Error("unexpected login allowed")
  2614. }
  2615. if !user.IsLoginAllowed("10.4.4.2") {
  2616. t.Error("unexpected login denied")
  2617. }
  2618. if !user.IsLoginAllowed("invalid") {
  2619. t.Error("unexpected login denied")
  2620. }
  2621. }
  2622. func TestSSHCommands(t *testing.T) {
  2623. usePubKey := false
  2624. user, _, err := httpd.AddUser(getTestUser(usePubKey), http.StatusOK)
  2625. if err != nil {
  2626. t.Errorf("unable to add user: %v", err)
  2627. }
  2628. _, err = runSSHCommand("ls", user, usePubKey)
  2629. if err == nil {
  2630. t.Errorf("unsupported ssh command must fail")
  2631. }
  2632. _, err = runSSHCommand("cd", user, usePubKey)
  2633. if err != nil {
  2634. t.Errorf("unexpected error for ssh cd command: %v", err)
  2635. }
  2636. out, err := runSSHCommand("pwd", user, usePubKey)
  2637. if err != nil {
  2638. t.Errorf("unexpected error: %v", err)
  2639. t.Fail()
  2640. }
  2641. if string(out) != "/\n" {
  2642. t.Errorf("invalid response for ssh pwd command: %v", string(out))
  2643. }
  2644. out, err = runSSHCommand("md5sum", user, usePubKey)
  2645. if err != nil {
  2646. t.Errorf("unexpected error: %v", err)
  2647. t.Fail()
  2648. }
  2649. // echo -n '' | md5sum
  2650. if !strings.Contains(string(out), "d41d8cd98f00b204e9800998ecf8427e") {
  2651. t.Errorf("invalid md5sum: %v", string(out))
  2652. }
  2653. out, err = runSSHCommand("sha1sum", user, usePubKey)
  2654. if err != nil {
  2655. t.Errorf("unexpected error: %v", err)
  2656. t.Fail()
  2657. }
  2658. if !strings.Contains(string(out), "da39a3ee5e6b4b0d3255bfef95601890afd80709") {
  2659. t.Errorf("invalid sha1sum: %v", string(out))
  2660. }
  2661. out, err = runSSHCommand("sha256sum", user, usePubKey)
  2662. if err != nil {
  2663. t.Errorf("unexpected error: %v", err)
  2664. t.Fail()
  2665. }
  2666. if !strings.Contains(string(out), "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855") {
  2667. t.Errorf("invalid sha256sum: %v", string(out))
  2668. }
  2669. out, err = runSSHCommand("sha384sum", user, usePubKey)
  2670. if err != nil {
  2671. t.Errorf("unexpected error: %v", err)
  2672. t.Fail()
  2673. }
  2674. if !strings.Contains(string(out), "38b060a751ac96384cd9327eb1b1e36a21fdb71114be07434c0cc7bf63f6e1da274edebfe76f65fbd51ad2f14898b95b") {
  2675. t.Errorf("invalid sha384sum: %v", string(out))
  2676. }
  2677. _, err = httpd.RemoveUser(user, http.StatusOK)
  2678. if err != nil {
  2679. t.Errorf("unable to remove user: %v", err)
  2680. }
  2681. }
  2682. func TestSSHFileHash(t *testing.T) {
  2683. usePubKey := true
  2684. user, _, err := httpd.AddUser(getTestUser(usePubKey), http.StatusOK)
  2685. if err != nil {
  2686. t.Errorf("unable to add user: %v", err)
  2687. }
  2688. client, err := getSftpClient(user, usePubKey)
  2689. if err != nil {
  2690. t.Errorf("unable to create sftp client: %v", err)
  2691. } else {
  2692. defer client.Close()
  2693. testFileName := "test_file.dat"
  2694. testFilePath := filepath.Join(homeBasePath, testFileName)
  2695. testFileSize := int64(65535)
  2696. err = createTestFile(testFilePath, testFileSize)
  2697. if err != nil {
  2698. t.Errorf("unable to create test file: %v", err)
  2699. }
  2700. err = sftpUploadFile(testFilePath, testFileName, testFileSize, client)
  2701. if err != nil {
  2702. t.Errorf("file upload error: %v", err)
  2703. }
  2704. user.Permissions = make(map[string][]string)
  2705. user.Permissions["/"] = []string{dataprovider.PermUpload}
  2706. _, _, err = httpd.UpdateUser(user, http.StatusOK)
  2707. if err != nil {
  2708. t.Errorf("unable to update user: %v", err)
  2709. }
  2710. _, err = runSSHCommand("sha512sum "+testFileName, user, usePubKey)
  2711. if err == nil {
  2712. t.Errorf("hash command with no list permission must fail")
  2713. }
  2714. user.Permissions["/"] = []string{dataprovider.PermAny}
  2715. _, _, err = httpd.UpdateUser(user, http.StatusOK)
  2716. if err != nil {
  2717. t.Errorf("unable to update user: %v", err)
  2718. }
  2719. initialHash, err := computeHashForFile(sha512.New(), testFilePath)
  2720. if err != nil {
  2721. t.Errorf("error computing file hash: %v", err)
  2722. }
  2723. out, err := runSSHCommand("sha512sum "+testFileName, user, usePubKey)
  2724. if err != nil {
  2725. t.Errorf("unexpected error: %v", err)
  2726. t.Fail()
  2727. }
  2728. if !strings.Contains(string(out), initialHash) {
  2729. t.Errorf("invalid sha512sum: %v", string(out))
  2730. }
  2731. _, err = runSSHCommand("sha512sum invalid_path", user, usePubKey)
  2732. if err == nil {
  2733. t.Errorf("hash for an invalid path must fail")
  2734. }
  2735. os.Remove(testFilePath)
  2736. }
  2737. _, err = httpd.RemoveUser(user, http.StatusOK)
  2738. if err != nil {
  2739. t.Errorf("unable to remove user: %v", err)
  2740. }
  2741. os.RemoveAll(user.GetHomeDir())
  2742. }
  2743. func TestBasicGitCommands(t *testing.T) {
  2744. if len(gitPath) == 0 || len(sshPath) == 0 {
  2745. t.Skip("git and/or ssh command not found, unable to execute this test")
  2746. }
  2747. usePubKey := true
  2748. u := getTestUser(usePubKey)
  2749. user, _, err := httpd.AddUser(u, http.StatusOK)
  2750. if err != nil {
  2751. t.Errorf("unable to add user: %v", err)
  2752. }
  2753. repoName := "testrepo"
  2754. clonePath := filepath.Join(homeBasePath, repoName)
  2755. os.RemoveAll(user.GetHomeDir())
  2756. os.RemoveAll(filepath.Join(homeBasePath, repoName))
  2757. out, err := initGitRepo(filepath.Join(user.HomeDir, repoName))
  2758. if err != nil {
  2759. t.Errorf("unexpected error: %v out: %v", err, string(out))
  2760. }
  2761. out, err = cloneGitRepo(homeBasePath, "/"+repoName, user.Username)
  2762. if err != nil {
  2763. t.Errorf("unexpected error: %v out: %v", err, string(out))
  2764. }
  2765. out, err = addFileToGitRepo(clonePath, 128)
  2766. if err != nil {
  2767. t.Errorf("unexpected error: %v out: %v", err, string(out))
  2768. }
  2769. user.QuotaFiles = 100000
  2770. _, _, err = httpd.UpdateUser(user, http.StatusOK)
  2771. if err != nil {
  2772. t.Errorf("unable to update user: %v", err)
  2773. }
  2774. out, err = pushToGitRepo(clonePath)
  2775. if err != nil {
  2776. t.Errorf("unexpected error: %v out: %v", err, string(out))
  2777. printLatestLogs(10)
  2778. }
  2779. err = waitQuotaScans()
  2780. if err != nil {
  2781. t.Errorf("error waiting for active quota scans: %v", err)
  2782. }
  2783. user, _, err = httpd.GetUserByID(user.ID, http.StatusOK)
  2784. if err != nil {
  2785. t.Errorf("unable to get user: %v", err)
  2786. }
  2787. user.QuotaSize = user.UsedQuotaSize - 1
  2788. _, _, err = httpd.UpdateUser(user, http.StatusOK)
  2789. if err != nil {
  2790. t.Errorf("unable to update user: %v", err)
  2791. }
  2792. out, err = pushToGitRepo(clonePath)
  2793. if err == nil {
  2794. t.Errorf("git push must fail if quota is exceeded, out: %v", string(out))
  2795. }
  2796. _, err = httpd.RemoveUser(user, http.StatusOK)
  2797. if err != nil {
  2798. t.Errorf("unable to remove user: %v", err)
  2799. }
  2800. os.RemoveAll(user.GetHomeDir())
  2801. os.RemoveAll(clonePath)
  2802. }
  2803. func TestGitErrors(t *testing.T) {
  2804. if len(gitPath) == 0 || len(sshPath) == 0 {
  2805. t.Skip("git and/or ssh command not found, unable to execute this test")
  2806. }
  2807. usePubKey := true
  2808. u := getTestUser(usePubKey)
  2809. user, _, err := httpd.AddUser(u, http.StatusOK)
  2810. if err != nil {
  2811. t.Errorf("unable to add user: %v", err)
  2812. }
  2813. repoName := "testrepo"
  2814. clonePath := filepath.Join(homeBasePath, repoName)
  2815. os.RemoveAll(user.GetHomeDir())
  2816. os.RemoveAll(filepath.Join(homeBasePath, repoName))
  2817. out, err := cloneGitRepo(homeBasePath, "/"+repoName, user.Username)
  2818. if err == nil {
  2819. t.Errorf("cloning a missing repo must fail, out: %v", string(out))
  2820. }
  2821. _, err = httpd.RemoveUser(user, http.StatusOK)
  2822. if err != nil {
  2823. t.Errorf("unable to remove user: %v", err)
  2824. }
  2825. os.RemoveAll(user.GetHomeDir())
  2826. os.RemoveAll(clonePath)
  2827. }
  2828. // Start SCP tests
  2829. func TestSCPBasicHandling(t *testing.T) {
  2830. if len(scpPath) == 0 {
  2831. t.Skip("scp command not found, unable to execute this test")
  2832. }
  2833. usePubKey := true
  2834. u := getTestUser(usePubKey)
  2835. u.QuotaSize = 6553600
  2836. user, _, err := httpd.AddUser(u, http.StatusOK)
  2837. if err != nil {
  2838. t.Errorf("unable to add user: %v", err)
  2839. }
  2840. testFileName := "test_file.dat"
  2841. testFilePath := filepath.Join(homeBasePath, testFileName)
  2842. testFileSize := int64(131074)
  2843. expectedQuotaSize := user.UsedQuotaSize + testFileSize
  2844. expectedQuotaFiles := user.UsedQuotaFiles + 1
  2845. err = createTestFile(testFilePath, testFileSize)
  2846. if err != nil {
  2847. t.Errorf("unable to create test file: %v", err)
  2848. }
  2849. remoteUpPath := fmt.Sprintf("%[email protected]:%v", user.Username, "/")
  2850. remoteDownPath := fmt.Sprintf("%[email protected]:%v", user.Username, path.Join("/", testFileName))
  2851. localPath := filepath.Join(homeBasePath, "scp_download.dat")
  2852. // test to download a missing file
  2853. err = scpDownload(localPath, remoteDownPath, false, false)
  2854. if err == nil {
  2855. t.Errorf("downloading a missing file via scp must fail")
  2856. }
  2857. err = scpUpload(testFilePath, remoteUpPath, false, false)
  2858. if err != nil {
  2859. t.Errorf("error uploading file via scp: %v", err)
  2860. }
  2861. err = scpDownload(localPath, remoteDownPath, false, false)
  2862. if err != nil {
  2863. t.Errorf("error downloading file via scp: %v", err)
  2864. }
  2865. fi, err := os.Stat(localPath)
  2866. if err != nil {
  2867. t.Errorf("stat for the downloaded file must succeed")
  2868. } else {
  2869. if fi.Size() != testFileSize {
  2870. t.Errorf("size of the file downloaded via SCP does not match the expected one")
  2871. }
  2872. }
  2873. os.Remove(localPath)
  2874. user, _, err = httpd.GetUserByID(user.ID, http.StatusOK)
  2875. if err != nil {
  2876. t.Errorf("error getting user: %v", err)
  2877. }
  2878. if expectedQuotaFiles != user.UsedQuotaFiles {
  2879. t.Errorf("quota files does not match, expected: %v, actual: %v", expectedQuotaFiles, user.UsedQuotaFiles)
  2880. }
  2881. if expectedQuotaSize != user.UsedQuotaSize {
  2882. t.Errorf("quota size does not match, expected: %v, actual: %v", expectedQuotaSize, user.UsedQuotaSize)
  2883. }
  2884. err = os.RemoveAll(user.GetHomeDir())
  2885. if err != nil {
  2886. t.Errorf("error removing uploaded files")
  2887. }
  2888. _, err = httpd.RemoveUser(user, http.StatusOK)
  2889. if err != nil {
  2890. t.Errorf("unable to remove user: %v", err)
  2891. }
  2892. os.Remove(testFilePath)
  2893. }
  2894. func TestSCPUploadFileOverwrite(t *testing.T) {
  2895. if len(scpPath) == 0 {
  2896. t.Skip("scp command not found, unable to execute this test")
  2897. }
  2898. usePubKey := true
  2899. u := getTestUser(usePubKey)
  2900. u.QuotaFiles = 1000
  2901. user, _, err := httpd.AddUser(u, http.StatusOK)
  2902. if err != nil {
  2903. t.Errorf("unable to add user: %v", err)
  2904. }
  2905. os.RemoveAll(user.GetHomeDir())
  2906. testFileName := "test_file.dat"
  2907. testFilePath := filepath.Join(homeBasePath, testFileName)
  2908. testFileSize := int64(32760)
  2909. err = createTestFile(testFilePath, testFileSize)
  2910. if err != nil {
  2911. t.Errorf("unable to create test file: %v", err)
  2912. }
  2913. remoteUpPath := fmt.Sprintf("%[email protected]:%v", user.Username, path.Join("/", testFileName))
  2914. err = scpUpload(testFilePath, remoteUpPath, true, false)
  2915. if err != nil {
  2916. t.Errorf("error uploading file via scp: %v", err)
  2917. }
  2918. // test a new upload that must overwrite the existing file
  2919. err = scpUpload(testFilePath, remoteUpPath, true, false)
  2920. if err != nil {
  2921. t.Errorf("error uploading existing file via scp: %v", err)
  2922. }
  2923. user, _, err = httpd.GetUserByID(user.ID, http.StatusOK)
  2924. if err != nil {
  2925. t.Errorf("error getting user: %v", err)
  2926. }
  2927. if user.UsedQuotaSize != testFileSize || user.UsedQuotaFiles != 1 {
  2928. t.Errorf("update quota error on file overwrite, actual size: %v, expected: %v actual files: %v, expected: 1",
  2929. user.UsedQuotaSize, testFileSize, user.UsedQuotaFiles)
  2930. }
  2931. remoteDownPath := fmt.Sprintf("%[email protected]:%v", user.Username, path.Join("/", testFileName))
  2932. localPath := filepath.Join(homeBasePath, "scp_download.dat")
  2933. err = scpDownload(localPath, remoteDownPath, false, false)
  2934. if err != nil {
  2935. t.Errorf("error downloading file via scp: %v", err)
  2936. }
  2937. fi, err := os.Stat(localPath)
  2938. if err != nil {
  2939. t.Errorf("stat for the downloaded file must succeed")
  2940. } else {
  2941. if fi.Size() != testFileSize {
  2942. t.Errorf("size of the file downloaded via SCP does not match the expected one")
  2943. }
  2944. }
  2945. os.Remove(localPath)
  2946. os.Remove(testFilePath)
  2947. err = os.RemoveAll(user.GetHomeDir())
  2948. if err != nil {
  2949. t.Errorf("error removing uploaded files")
  2950. }
  2951. _, err = httpd.RemoveUser(user, http.StatusOK)
  2952. if err != nil {
  2953. t.Errorf("unable to remove user: %v", err)
  2954. }
  2955. }
  2956. func TestSCPRecursive(t *testing.T) {
  2957. if len(scpPath) == 0 {
  2958. t.Skip("scp command not found, unable to execute this test")
  2959. }
  2960. usePubKey := true
  2961. u := getTestUser(usePubKey)
  2962. user, _, err := httpd.AddUser(u, http.StatusOK)
  2963. if err != nil {
  2964. t.Errorf("unable to add user: %v", err)
  2965. }
  2966. testFileName := "test_file.dat"
  2967. testBaseDirName := "test_dir"
  2968. testBaseDirPath := filepath.Join(homeBasePath, testBaseDirName)
  2969. testBaseDirDownName := "test_dir_down"
  2970. testBaseDirDownPath := filepath.Join(homeBasePath, testBaseDirDownName)
  2971. testFilePath := filepath.Join(homeBasePath, testBaseDirName, testFileName)
  2972. testFilePath1 := filepath.Join(homeBasePath, testBaseDirName, testBaseDirName, testFileName)
  2973. testFileSize := int64(131074)
  2974. createTestFile(testFilePath, testFileSize)
  2975. createTestFile(testFilePath1, testFileSize)
  2976. remoteDownPath := fmt.Sprintf("%[email protected]:%v", user.Username, path.Join("/", testBaseDirName))
  2977. // test to download a missing dir
  2978. err = scpDownload(testBaseDirDownPath, remoteDownPath, true, true)
  2979. if err == nil {
  2980. t.Errorf("downloading a missing dir via scp must fail")
  2981. }
  2982. remoteUpPath := fmt.Sprintf("%[email protected]:%v", user.Username, "/")
  2983. err = scpUpload(testBaseDirPath, remoteUpPath, true, false)
  2984. if err != nil {
  2985. t.Errorf("error uploading dir via scp: %v", err)
  2986. }
  2987. err = scpDownload(testBaseDirDownPath, remoteDownPath, true, true)
  2988. if err != nil {
  2989. t.Errorf("error downloading dir via scp: %v", err)
  2990. }
  2991. // test download without passing -r
  2992. err = scpDownload(testBaseDirDownPath, remoteDownPath, true, false)
  2993. if err == nil {
  2994. t.Errorf("recursive download without -r must fail")
  2995. }
  2996. fi, err := os.Stat(filepath.Join(testBaseDirDownPath, testFileName))
  2997. if err != nil {
  2998. t.Errorf("error downloading file using scp recursive: %v", err)
  2999. } else {
  3000. if fi.Size() != testFileSize {
  3001. t.Errorf("size for file downloaded using recursive scp does not match, actual: %v, expected: %v", fi.Size(), testFileSize)
  3002. }
  3003. }
  3004. fi, err = os.Stat(filepath.Join(testBaseDirDownPath, testBaseDirName, testFileName))
  3005. if err != nil {
  3006. t.Errorf("error downloading file using scp recursive: %v", err)
  3007. } else {
  3008. if fi.Size() != testFileSize {
  3009. t.Errorf("size for file downloaded using recursive scp does not match, actual: %v, expected: %v", fi.Size(), testFileSize)
  3010. }
  3011. }
  3012. // upload to a non existent dir
  3013. remoteUpPath = fmt.Sprintf("%[email protected]:%v", user.Username, "/non_existent_dir")
  3014. err = scpUpload(testBaseDirPath, remoteUpPath, true, false)
  3015. if err == nil {
  3016. t.Errorf("uploading via scp to a non existent dir must fail")
  3017. }
  3018. os.RemoveAll(testBaseDirPath)
  3019. os.RemoveAll(testBaseDirDownPath)
  3020. err = os.RemoveAll(user.GetHomeDir())
  3021. if err != nil {
  3022. t.Errorf("error removing uploaded files")
  3023. }
  3024. _, err = httpd.RemoveUser(user, http.StatusOK)
  3025. if err != nil {
  3026. t.Errorf("unable to remove user: %v", err)
  3027. }
  3028. }
  3029. func TestSCPPermsSubDirs(t *testing.T) {
  3030. if len(scpPath) == 0 {
  3031. t.Skip("scp command not found, unable to execute this test")
  3032. }
  3033. usePubKey := true
  3034. u := getTestUser(usePubKey)
  3035. u.Permissions["/"] = []string{dataprovider.PermAny}
  3036. u.Permissions["/somedir"] = []string{dataprovider.PermListItems, dataprovider.PermUpload}
  3037. user, _, err := httpd.AddUser(u, http.StatusOK)
  3038. if err != nil {
  3039. t.Errorf("unable to add user: %v", err)
  3040. }
  3041. localPath := filepath.Join(homeBasePath, "scp_download.dat")
  3042. subPath := filepath.Join(user.GetHomeDir(), "somedir")
  3043. testFileSize := int64(65535)
  3044. os.MkdirAll(subPath, 0777)
  3045. remoteDownPath := fmt.Sprintf("%[email protected]:%v", user.Username, "/somedir")
  3046. err = scpDownload(localPath, remoteDownPath, false, true)
  3047. if err == nil {
  3048. t.Error("download a dir with no permissions must fail")
  3049. }
  3050. os.Remove(subPath)
  3051. err = createTestFile(subPath, testFileSize)
  3052. if err != nil {
  3053. t.Errorf("unable to create test file: %v", err)
  3054. }
  3055. err = scpDownload(localPath, remoteDownPath, false, false)
  3056. if err != nil {
  3057. t.Errorf("unexpected download error: %v", err)
  3058. }
  3059. os.Chmod(subPath, 0001)
  3060. err = scpDownload(localPath, remoteDownPath, false, false)
  3061. if err == nil {
  3062. t.Error("download a file with no system permissions must fail")
  3063. }
  3064. os.Chmod(subPath, 0755)
  3065. os.Remove(localPath)
  3066. os.RemoveAll(user.GetHomeDir())
  3067. _, err = httpd.RemoveUser(user, http.StatusOK)
  3068. if err != nil {
  3069. t.Errorf("unable to remove user: %v", err)
  3070. }
  3071. }
  3072. func TestSCPPermCreateDirs(t *testing.T) {
  3073. if len(scpPath) == 0 {
  3074. t.Skip("scp command not found, unable to execute this test")
  3075. }
  3076. usePubKey := true
  3077. u := getTestUser(usePubKey)
  3078. u.Permissions["/"] = []string{dataprovider.PermDownload, dataprovider.PermUpload}
  3079. user, _, err := httpd.AddUser(u, http.StatusOK)
  3080. if err != nil {
  3081. t.Errorf("unable to add user: %v", err)
  3082. }
  3083. testFileName := "test_file.dat"
  3084. testFilePath := filepath.Join(homeBasePath, testFileName)
  3085. testFileSize := int64(32760)
  3086. testBaseDirName := "test_dir"
  3087. testBaseDirPath := filepath.Join(homeBasePath, testBaseDirName)
  3088. testFilePath1 := filepath.Join(homeBasePath, testBaseDirName, testFileName)
  3089. err = createTestFile(testFilePath, testFileSize)
  3090. if err != nil {
  3091. t.Errorf("unable to create test file: %v", err)
  3092. }
  3093. err = createTestFile(testFilePath1, testFileSize)
  3094. if err != nil {
  3095. t.Errorf("unable to create test file: %v", err)
  3096. }
  3097. remoteUpPath := fmt.Sprintf("%[email protected]:%v", user.Username, "/tmp/")
  3098. err = scpUpload(testFilePath, remoteUpPath, true, false)
  3099. if err == nil {
  3100. t.Errorf("scp upload must fail, the user cannot create files in a missing dir")
  3101. }
  3102. err = scpUpload(testBaseDirPath, remoteUpPath, true, false)
  3103. if err == nil {
  3104. t.Errorf("scp upload must fail, the user cannot create new dirs")
  3105. }
  3106. err = os.Remove(testFilePath)
  3107. if err != nil {
  3108. t.Errorf("error removing test file")
  3109. }
  3110. os.RemoveAll(testBaseDirPath)
  3111. err = os.RemoveAll(user.GetHomeDir())
  3112. if err != nil {
  3113. t.Errorf("error removing uploaded files")
  3114. }
  3115. _, err = httpd.RemoveUser(user, http.StatusOK)
  3116. if err != nil {
  3117. t.Errorf("unable to remove user: %v", err)
  3118. }
  3119. }
  3120. func TestSCPPermUpload(t *testing.T) {
  3121. if len(scpPath) == 0 {
  3122. t.Skip("scp command not found, unable to execute this test")
  3123. }
  3124. usePubKey := true
  3125. u := getTestUser(usePubKey)
  3126. u.Permissions["/"] = []string{dataprovider.PermDownload, dataprovider.PermCreateDirs}
  3127. user, _, err := httpd.AddUser(u, http.StatusOK)
  3128. if err != nil {
  3129. t.Errorf("unable to add user: %v", err)
  3130. }
  3131. testFileName := "test_file.dat"
  3132. testFilePath := filepath.Join(homeBasePath, testFileName)
  3133. testFileSize := int64(65536)
  3134. err = createTestFile(testFilePath, testFileSize)
  3135. if err != nil {
  3136. t.Errorf("unable to create test file: %v", err)
  3137. }
  3138. remoteUpPath := fmt.Sprintf("%[email protected]:%v", user.Username, "/tmp")
  3139. err = scpUpload(testFilePath, remoteUpPath, true, false)
  3140. if err == nil {
  3141. t.Errorf("scp upload must fail, the user cannot upload")
  3142. }
  3143. err = os.Remove(testFilePath)
  3144. if err != nil {
  3145. t.Errorf("error removing test file")
  3146. }
  3147. err = os.RemoveAll(user.GetHomeDir())
  3148. if err != nil {
  3149. t.Errorf("error removing uploaded files")
  3150. }
  3151. _, err = httpd.RemoveUser(user, http.StatusOK)
  3152. if err != nil {
  3153. t.Errorf("unable to remove user: %v", err)
  3154. }
  3155. }
  3156. func TestSCPPermOverwrite(t *testing.T) {
  3157. if len(scpPath) == 0 {
  3158. t.Skip("scp command not found, unable to execute this test")
  3159. }
  3160. usePubKey := true
  3161. u := getTestUser(usePubKey)
  3162. u.Permissions["/"] = []string{dataprovider.PermUpload, dataprovider.PermCreateDirs}
  3163. user, _, err := httpd.AddUser(u, http.StatusOK)
  3164. if err != nil {
  3165. t.Errorf("unable to add user: %v", err)
  3166. }
  3167. testFileName := "test_file.dat"
  3168. testFilePath := filepath.Join(homeBasePath, testFileName)
  3169. testFileSize := int64(65536)
  3170. err = createTestFile(testFilePath, testFileSize)
  3171. if err != nil {
  3172. t.Errorf("unable to create test file: %v", err)
  3173. }
  3174. remoteUpPath := fmt.Sprintf("%[email protected]:%v", user.Username, "/tmp")
  3175. err = scpUpload(testFilePath, remoteUpPath, true, false)
  3176. if err != nil {
  3177. t.Errorf("scp upload error: %v", err)
  3178. }
  3179. err = scpUpload(testFilePath, remoteUpPath, true, false)
  3180. if err == nil {
  3181. t.Errorf("scp upload must fail, the user cannot ovewrite existing files")
  3182. }
  3183. err = os.Remove(testFilePath)
  3184. if err != nil {
  3185. t.Errorf("error removing test file")
  3186. }
  3187. err = os.RemoveAll(user.GetHomeDir())
  3188. if err != nil {
  3189. t.Errorf("error removing uploaded files")
  3190. }
  3191. _, err = httpd.RemoveUser(user, http.StatusOK)
  3192. if err != nil {
  3193. t.Errorf("unable to remove user: %v", err)
  3194. }
  3195. }
  3196. func TestSCPPermDownload(t *testing.T) {
  3197. if len(scpPath) == 0 {
  3198. t.Skip("scp command not found, unable to execute this test")
  3199. }
  3200. usePubKey := true
  3201. u := getTestUser(usePubKey)
  3202. u.Permissions["/"] = []string{dataprovider.PermUpload, dataprovider.PermCreateDirs}
  3203. user, _, err := httpd.AddUser(u, http.StatusOK)
  3204. if err != nil {
  3205. t.Errorf("unable to add user: %v", err)
  3206. }
  3207. testFileName := "test_file.dat"
  3208. testFilePath := filepath.Join(homeBasePath, testFileName)
  3209. testFileSize := int64(65537)
  3210. err = createTestFile(testFilePath, testFileSize)
  3211. if err != nil {
  3212. t.Errorf("unable to create test file: %v", err)
  3213. }
  3214. remoteUpPath := fmt.Sprintf("%[email protected]:%v", user.Username, "/")
  3215. err = scpUpload(testFilePath, remoteUpPath, true, false)
  3216. if err != nil {
  3217. t.Errorf("error uploading existing file via scp: %v", err)
  3218. }
  3219. remoteDownPath := fmt.Sprintf("%[email protected]:%v", user.Username, path.Join("/", testFileName))
  3220. localPath := filepath.Join(homeBasePath, "scp_download.dat")
  3221. err = scpDownload(localPath, remoteDownPath, false, false)
  3222. if err == nil {
  3223. t.Errorf("scp download must fail, the user cannot download")
  3224. }
  3225. err = os.Remove(testFilePath)
  3226. if err != nil {
  3227. t.Errorf("error removing test file")
  3228. }
  3229. err = os.RemoveAll(user.GetHomeDir())
  3230. if err != nil {
  3231. t.Errorf("error removing uploaded files")
  3232. }
  3233. _, err = httpd.RemoveUser(user, http.StatusOK)
  3234. if err != nil {
  3235. t.Errorf("unable to remove user: %v", err)
  3236. }
  3237. }
  3238. func TestSCPQuotaSize(t *testing.T) {
  3239. if len(scpPath) == 0 {
  3240. t.Skip("scp command not found, unable to execute this test")
  3241. }
  3242. usePubKey := true
  3243. testFileSize := int64(65535)
  3244. u := getTestUser(usePubKey)
  3245. u.QuotaFiles = 1
  3246. u.QuotaSize = testFileSize - 1
  3247. user, _, err := httpd.AddUser(u, http.StatusOK)
  3248. if err != nil {
  3249. t.Errorf("unable to add user: %v", err)
  3250. }
  3251. testFileName := "test_file.dat"
  3252. testFilePath := filepath.Join(homeBasePath, testFileName)
  3253. err = createTestFile(testFilePath, testFileSize)
  3254. if err != nil {
  3255. t.Errorf("unable to create test file: %v", err)
  3256. }
  3257. remoteUpPath := fmt.Sprintf("%[email protected]:%v", user.Username, path.Join("/", testFileName))
  3258. err = scpUpload(testFilePath, remoteUpPath, true, false)
  3259. if err != nil {
  3260. t.Errorf("error uploading existing file via scp: %v", err)
  3261. }
  3262. err = scpUpload(testFilePath, remoteUpPath+".quota", true, false)
  3263. if err == nil {
  3264. t.Errorf("user is over quota scp upload must fail")
  3265. }
  3266. err = os.Remove(testFilePath)
  3267. if err != nil {
  3268. t.Errorf("error removing test file")
  3269. }
  3270. err = os.RemoveAll(user.GetHomeDir())
  3271. if err != nil {
  3272. t.Errorf("error removing uploaded files")
  3273. }
  3274. _, err = httpd.RemoveUser(user, http.StatusOK)
  3275. if err != nil {
  3276. t.Errorf("unable to remove user: %v", err)
  3277. }
  3278. }
  3279. func TestSCPEscapeHomeDir(t *testing.T) {
  3280. if len(scpPath) == 0 {
  3281. t.Skip("scp command not found, unable to execute this test")
  3282. }
  3283. usePubKey := true
  3284. user, _, err := httpd.AddUser(getTestUser(usePubKey), http.StatusOK)
  3285. if err != nil {
  3286. t.Errorf("unable to add user: %v", err)
  3287. }
  3288. os.MkdirAll(user.GetHomeDir(), 0777)
  3289. testDir := "testDir"
  3290. linkPath := filepath.Join(homeBasePath, defaultUsername, testDir)
  3291. err = os.Symlink(homeBasePath, linkPath)
  3292. if err != nil {
  3293. t.Errorf("error making local symlink: %v", err)
  3294. }
  3295. testFileName := "test_file.dat"
  3296. testFilePath := filepath.Join(homeBasePath, testFileName)
  3297. testFileSize := int64(65535)
  3298. err = createTestFile(testFilePath, testFileSize)
  3299. if err != nil {
  3300. t.Errorf("unable to create test file: %v", err)
  3301. }
  3302. remoteUpPath := fmt.Sprintf("%[email protected]:%v", user.Username, path.Join(testDir, testDir))
  3303. err = scpUpload(testFilePath, remoteUpPath, false, false)
  3304. if err == nil {
  3305. t.Errorf("uploading to a dir with a symlink outside home dir must fail")
  3306. }
  3307. remoteDownPath := fmt.Sprintf("%[email protected]:%v", user.Username, path.Join("/", testDir, testFileName))
  3308. localPath := filepath.Join(homeBasePath, "scp_download.dat")
  3309. err = scpDownload(localPath, remoteDownPath, false, false)
  3310. if err == nil {
  3311. t.Errorf("scp download must fail, the requested file has a symlink outside user home")
  3312. }
  3313. remoteDownPath = fmt.Sprintf("%[email protected]:%v", user.Username, path.Join("/", testDir))
  3314. err = scpDownload(homeBasePath, remoteDownPath, false, true)
  3315. if err == nil {
  3316. t.Errorf("scp download must fail, the requested dir is a symlink outside user home")
  3317. }
  3318. err = os.Remove(testFilePath)
  3319. if err != nil {
  3320. t.Errorf("error removing test file")
  3321. }
  3322. err = os.RemoveAll(user.GetHomeDir())
  3323. if err != nil {
  3324. t.Errorf("error removing uploaded files")
  3325. }
  3326. _, err = httpd.RemoveUser(user, http.StatusOK)
  3327. if err != nil {
  3328. t.Errorf("unable to remove user: %v", err)
  3329. }
  3330. }
  3331. func TestSCPUploadPaths(t *testing.T) {
  3332. if len(scpPath) == 0 {
  3333. t.Skip("scp command not found, unable to execute this test")
  3334. }
  3335. usePubKey := true
  3336. user, _, err := httpd.AddUser(getTestUser(usePubKey), http.StatusOK)
  3337. if err != nil {
  3338. t.Errorf("unable to add user: %v", err)
  3339. }
  3340. testFileName := "test_file.dat"
  3341. testFilePath := filepath.Join(homeBasePath, testFileName)
  3342. testFileSize := int64(65535)
  3343. testDirName := "testDir"
  3344. testDirPath := filepath.Join(user.GetHomeDir(), testDirName)
  3345. os.MkdirAll(testDirPath, 0777)
  3346. err = createTestFile(testFilePath, testFileSize)
  3347. if err != nil {
  3348. t.Errorf("unable to create test file: %v", err)
  3349. }
  3350. remoteUpPath := fmt.Sprintf("%[email protected]:%v", user.Username, testDirName)
  3351. remoteDownPath := fmt.Sprintf("%[email protected]:%v", user.Username, path.Join(testDirName, testFileName))
  3352. localPath := filepath.Join(homeBasePath, "scp_download.dat")
  3353. err = scpUpload(testFilePath, remoteUpPath, false, false)
  3354. if err != nil {
  3355. t.Errorf("scp upload error: %v", err)
  3356. }
  3357. err = scpDownload(localPath, remoteDownPath, false, false)
  3358. if err != nil {
  3359. t.Errorf("scp download error: %v", err)
  3360. }
  3361. // upload a file to a missing dir
  3362. remoteUpPath = fmt.Sprintf("%[email protected]:%v", user.Username, path.Join(testDirName, testDirName, testFileName))
  3363. err = scpUpload(testFilePath, remoteUpPath, false, false)
  3364. if err == nil {
  3365. t.Errorf("scp upload to a missing dir must fail")
  3366. }
  3367. err = os.RemoveAll(user.GetHomeDir())
  3368. if err != nil {
  3369. t.Errorf("error removing uploaded files")
  3370. }
  3371. os.Remove(localPath)
  3372. _, err = httpd.RemoveUser(user, http.StatusOK)
  3373. if err != nil {
  3374. t.Errorf("unable to remove user: %v", err)
  3375. }
  3376. }
  3377. func TestSCPOverwriteDirWithFile(t *testing.T) {
  3378. if len(scpPath) == 0 {
  3379. t.Skip("scp command not found, unable to execute this test")
  3380. }
  3381. usePubKey := true
  3382. user, _, err := httpd.AddUser(getTestUser(usePubKey), http.StatusOK)
  3383. if err != nil {
  3384. t.Errorf("unable to add user: %v", err)
  3385. }
  3386. testFileName := "test_file.dat"
  3387. testFilePath := filepath.Join(homeBasePath, testFileName)
  3388. testFileSize := int64(65535)
  3389. testDirPath := filepath.Join(user.GetHomeDir(), testFileName)
  3390. os.MkdirAll(testDirPath, 0777)
  3391. err = createTestFile(testFilePath, testFileSize)
  3392. if err != nil {
  3393. t.Errorf("unable to create test file: %v", err)
  3394. }
  3395. remoteUpPath := fmt.Sprintf("%[email protected]:%v", user.Username, "/")
  3396. err = scpUpload(testFilePath, remoteUpPath, false, false)
  3397. if err == nil {
  3398. t.Errorf("copying a file over an existing dir must fail")
  3399. }
  3400. err = os.RemoveAll(user.GetHomeDir())
  3401. if err != nil {
  3402. t.Errorf("error removing uploaded files")
  3403. }
  3404. _, err = httpd.RemoveUser(user, http.StatusOK)
  3405. if err != nil {
  3406. t.Errorf("unable to remove user: %v", err)
  3407. }
  3408. }
  3409. func TestSCPRemoteToRemote(t *testing.T) {
  3410. if len(scpPath) == 0 {
  3411. t.Skip("scp command not found, unable to execute this test")
  3412. }
  3413. usePubKey := true
  3414. user, _, err := httpd.AddUser(getTestUser(usePubKey), http.StatusOK)
  3415. if err != nil {
  3416. t.Errorf("unable to add user: %v", err)
  3417. }
  3418. u := getTestUser(usePubKey)
  3419. u.Username += "1"
  3420. u.HomeDir += "1"
  3421. user1, _, err := httpd.AddUser(u, http.StatusOK)
  3422. if err != nil {
  3423. t.Errorf("unable to add user: %v", err)
  3424. }
  3425. testFileName := "test_file.dat"
  3426. testFilePath := filepath.Join(homeBasePath, testFileName)
  3427. testFileSize := int64(65535)
  3428. err = createTestFile(testFilePath, testFileSize)
  3429. if err != nil {
  3430. t.Errorf("unable to create test file: %v", err)
  3431. }
  3432. remoteUpPath := fmt.Sprintf("%[email protected]:%v", user.Username, path.Join("/", testFileName))
  3433. remote1UpPath := fmt.Sprintf("%[email protected]:%v", user1.Username, path.Join("/", testFileName))
  3434. err = scpUpload(testFilePath, remoteUpPath, false, false)
  3435. if err != nil {
  3436. t.Errorf("scp upload error: %v", err)
  3437. }
  3438. err = scpUpload(remoteUpPath, remote1UpPath, false, true)
  3439. if err != nil {
  3440. t.Errorf("scp upload remote to remote error: %v", err)
  3441. }
  3442. err = os.RemoveAll(user.GetHomeDir())
  3443. if err != nil {
  3444. t.Errorf("error removing uploaded files")
  3445. }
  3446. _, err = httpd.RemoveUser(user, http.StatusOK)
  3447. if err != nil {
  3448. t.Errorf("unable to remove user: %v", err)
  3449. }
  3450. err = os.RemoveAll(user1.GetHomeDir())
  3451. if err != nil {
  3452. t.Errorf("error removing uploaded files for user1")
  3453. }
  3454. _, err = httpd.RemoveUser(user1, http.StatusOK)
  3455. if err != nil {
  3456. t.Errorf("unable to remove user1: %v", err)
  3457. }
  3458. }
  3459. func TestSCPErrors(t *testing.T) {
  3460. if len(scpPath) == 0 {
  3461. t.Skip("scp command not found, unable to execute this test")
  3462. }
  3463. u := getTestUser(true)
  3464. user, _, err := httpd.AddUser(u, http.StatusOK)
  3465. if err != nil {
  3466. t.Errorf("unable to add user: %v", err)
  3467. }
  3468. testFileSize := int64(524288)
  3469. testFileName := "test_file.dat"
  3470. testFilePath := filepath.Join(homeBasePath, testFileName)
  3471. err = createTestFile(testFilePath, testFileSize)
  3472. if err != nil {
  3473. t.Errorf("unable to create test file: %v", err)
  3474. }
  3475. remoteUpPath := fmt.Sprintf("%[email protected]:%v", user.Username, "/")
  3476. remoteDownPath := fmt.Sprintf("%[email protected]:%v", user.Username, path.Join("/", testFileName))
  3477. localPath := filepath.Join(homeBasePath, "scp_download.dat")
  3478. err = scpUpload(testFilePath, remoteUpPath, false, false)
  3479. if err != nil {
  3480. t.Errorf("error uploading file via scp: %v", err)
  3481. }
  3482. user.UploadBandwidth = 512
  3483. user.DownloadBandwidth = 512
  3484. _, _, err = httpd.UpdateUser(user, http.StatusOK)
  3485. if err != nil {
  3486. t.Errorf("unable to update user: %v", err)
  3487. }
  3488. cmd := getScpDownloadCommand(localPath, remoteDownPath, false, false)
  3489. go func() {
  3490. if cmd.Run() == nil {
  3491. t.Errorf("SCP download must fail")
  3492. }
  3493. }()
  3494. waitForActiveTransfer()
  3495. // wait some additional arbitrary time to wait for transfer activity to happen
  3496. // it is need to reach all the code in CheckIdleConnections
  3497. time.Sleep(100 * time.Millisecond)
  3498. cmd.Process.Kill()
  3499. waitForNoActiveTransfer()
  3500. cmd = getScpUploadCommand(testFilePath, remoteUpPath, false, false)
  3501. go func() {
  3502. if cmd.Run() == nil {
  3503. t.Errorf("SCP upload must fail")
  3504. }
  3505. }()
  3506. waitForActiveTransfer()
  3507. // wait some additional arbitrary time to wait for transfer activity to happen
  3508. // it is need to reach all the code in CheckIdleConnections
  3509. time.Sleep(100 * time.Millisecond)
  3510. cmd.Process.Kill()
  3511. waitForNoActiveTransfer()
  3512. err = os.Remove(testFilePath)
  3513. if err != nil {
  3514. t.Errorf("error removing test file")
  3515. }
  3516. os.Remove(localPath)
  3517. err = os.RemoveAll(user.GetHomeDir())
  3518. if err != nil {
  3519. t.Errorf("error removing uploaded files")
  3520. }
  3521. _, err = httpd.RemoveUser(user, http.StatusOK)
  3522. if err != nil {
  3523. t.Errorf("unable to remove user: %v", err)
  3524. }
  3525. }
  3526. // End SCP tests
  3527. func waitTCPListening(address string) {
  3528. for {
  3529. conn, err := net.Dial("tcp", address)
  3530. if err != nil {
  3531. logger.WarnToConsole("tcp server %v not listening: %v\n", address, err)
  3532. time.Sleep(100 * time.Millisecond)
  3533. continue
  3534. }
  3535. logger.InfoToConsole("tcp server %v now listening\n", address)
  3536. defer conn.Close()
  3537. break
  3538. }
  3539. }
  3540. func getTestUser(usePubKey bool) dataprovider.User {
  3541. user := dataprovider.User{
  3542. Username: defaultUsername,
  3543. Password: defaultPassword,
  3544. HomeDir: filepath.Join(homeBasePath, defaultUsername),
  3545. Status: 1,
  3546. ExpirationDate: 0,
  3547. }
  3548. user.Permissions = make(map[string][]string)
  3549. user.Permissions["/"] = allPerms
  3550. if usePubKey {
  3551. user.PublicKeys = []string{testPubKey}
  3552. user.Password = ""
  3553. }
  3554. return user
  3555. }
  3556. func runSSHCommand(command string, user dataprovider.User, usePubKey bool) ([]byte, error) {
  3557. var sshSession *ssh.Session
  3558. var output []byte
  3559. config := &ssh.ClientConfig{
  3560. User: defaultUsername,
  3561. HostKeyCallback: func(hostname string, remote net.Addr, key ssh.PublicKey) error {
  3562. return nil
  3563. },
  3564. }
  3565. if usePubKey {
  3566. key, err := ssh.ParsePrivateKey([]byte(testPrivateKey))
  3567. if err != nil {
  3568. return output, err
  3569. }
  3570. config.Auth = []ssh.AuthMethod{ssh.PublicKeys(key)}
  3571. } else {
  3572. config.Auth = []ssh.AuthMethod{ssh.Password(defaultPassword)}
  3573. }
  3574. conn, err := ssh.Dial("tcp", sftpServerAddr, config)
  3575. if err != nil {
  3576. return output, err
  3577. }
  3578. defer conn.Close()
  3579. sshSession, err = conn.NewSession()
  3580. if err != nil {
  3581. return output, err
  3582. }
  3583. var stdout, stderr bytes.Buffer
  3584. sshSession.Stdout = &stdout
  3585. sshSession.Stderr = &stderr
  3586. err = sshSession.Run(command)
  3587. if err != nil {
  3588. return nil, fmt.Errorf("failed to run command %v: %v", command, stderr.Bytes())
  3589. }
  3590. return stdout.Bytes(), err
  3591. }
  3592. func getSftpClient(user dataprovider.User, usePubKey bool) (*sftp.Client, error) {
  3593. var sftpClient *sftp.Client
  3594. config := &ssh.ClientConfig{
  3595. User: user.Username,
  3596. HostKeyCallback: func(hostname string, remote net.Addr, key ssh.PublicKey) error {
  3597. return nil
  3598. },
  3599. }
  3600. if usePubKey {
  3601. key, err := ssh.ParsePrivateKey([]byte(testPrivateKey))
  3602. if err != nil {
  3603. return nil, err
  3604. }
  3605. config.Auth = []ssh.AuthMethod{ssh.PublicKeys(key)}
  3606. } else {
  3607. if len(user.Password) > 0 {
  3608. config.Auth = []ssh.AuthMethod{ssh.Password(user.Password)}
  3609. } else {
  3610. config.Auth = []ssh.AuthMethod{ssh.Password(defaultPassword)}
  3611. }
  3612. }
  3613. conn, err := ssh.Dial("tcp", sftpServerAddr, config)
  3614. if err != nil {
  3615. return sftpClient, err
  3616. }
  3617. sftpClient, err = sftp.NewClient(conn)
  3618. return sftpClient, err
  3619. }
  3620. func createTestFile(path string, size int64) error {
  3621. baseDir := filepath.Dir(path)
  3622. if _, err := os.Stat(baseDir); os.IsNotExist(err) {
  3623. os.MkdirAll(baseDir, 0777)
  3624. }
  3625. content := make([]byte, size)
  3626. _, err := rand.Read(content)
  3627. if err != nil {
  3628. return err
  3629. }
  3630. return ioutil.WriteFile(path, content, 0666)
  3631. }
  3632. func appendToTestFile(path string, size int64) error {
  3633. content := make([]byte, size)
  3634. _, err := rand.Read(content)
  3635. if err != nil {
  3636. return err
  3637. }
  3638. f, err := os.OpenFile(path, os.O_APPEND|os.O_WRONLY, 0666)
  3639. if err != nil {
  3640. return err
  3641. }
  3642. written, err := io.Copy(f, bytes.NewReader(content))
  3643. if err != nil {
  3644. return err
  3645. }
  3646. if int64(written) != size {
  3647. return fmt.Errorf("write error, written: %v/%v", written, size)
  3648. }
  3649. return nil
  3650. }
  3651. func sftpUploadFile(localSourcePath string, remoteDestPath string, expectedSize int64, client *sftp.Client) error {
  3652. srcFile, err := os.Open(localSourcePath)
  3653. if err != nil {
  3654. return err
  3655. }
  3656. defer srcFile.Close()
  3657. destFile, err := client.Create(remoteDestPath)
  3658. if err != nil {
  3659. return err
  3660. }
  3661. _, err = io.Copy(destFile, srcFile)
  3662. if err != nil {
  3663. destFile.Close()
  3664. return err
  3665. }
  3666. // we need to close the file to trigger the close method on server
  3667. // we cannot defer closing or Lstat will fail for uploads in atomic mode
  3668. destFile.Close()
  3669. if expectedSize > 0 {
  3670. fi, err := client.Stat(remoteDestPath)
  3671. if err != nil {
  3672. return err
  3673. }
  3674. if fi.Size() != expectedSize {
  3675. return fmt.Errorf("uploaded file size does not match, actual: %v, expected: %v", fi.Size(), expectedSize)
  3676. }
  3677. }
  3678. return err
  3679. }
  3680. func sftpUploadResumeFile(localSourcePath string, remoteDestPath string, expectedSize int64, invalidOffset bool,
  3681. client *sftp.Client) error {
  3682. srcFile, err := os.Open(localSourcePath)
  3683. if err != nil {
  3684. return err
  3685. }
  3686. defer srcFile.Close()
  3687. fi, err := client.Lstat(remoteDestPath)
  3688. if err != nil {
  3689. return err
  3690. }
  3691. if !invalidOffset {
  3692. _, err = srcFile.Seek(fi.Size(), 0)
  3693. if err != nil {
  3694. return err
  3695. }
  3696. }
  3697. destFile, err := client.OpenFile(remoteDestPath, os.O_WRONLY|os.O_APPEND)
  3698. if err != nil {
  3699. return err
  3700. }
  3701. if !invalidOffset {
  3702. _, err = destFile.Seek(fi.Size(), 0)
  3703. if err != nil {
  3704. return err
  3705. }
  3706. }
  3707. _, err = io.Copy(destFile, srcFile)
  3708. if err != nil {
  3709. destFile.Close()
  3710. return err
  3711. }
  3712. // we need to close the file to trigger the close method on server
  3713. // we cannot defer closing or Lstat will fail for upload atomic mode
  3714. destFile.Close()
  3715. if expectedSize > 0 {
  3716. fi, err := client.Lstat(remoteDestPath)
  3717. if err != nil {
  3718. return err
  3719. }
  3720. if fi.Size() != expectedSize {
  3721. return fmt.Errorf("uploaded file size does not match, actual: %v, expected: %v", fi.Size(), expectedSize)
  3722. }
  3723. }
  3724. return err
  3725. }
  3726. func sftpDownloadFile(remoteSourcePath string, localDestPath string, expectedSize int64, client *sftp.Client) error {
  3727. downloadDest, err := os.Create(localDestPath)
  3728. if err != nil {
  3729. return err
  3730. }
  3731. defer downloadDest.Close()
  3732. sftpSrcFile, err := client.Open(remoteSourcePath)
  3733. if err != nil {
  3734. return err
  3735. }
  3736. defer sftpSrcFile.Close()
  3737. _, err = io.Copy(downloadDest, sftpSrcFile)
  3738. if err != nil {
  3739. return err
  3740. }
  3741. err = downloadDest.Sync()
  3742. if err != nil {
  3743. return err
  3744. }
  3745. if expectedSize > 0 {
  3746. fi, err := downloadDest.Stat()
  3747. if err != nil {
  3748. return err
  3749. }
  3750. if fi.Size() != expectedSize {
  3751. return fmt.Errorf("downloaded file size does not match, actual: %v, expected: %v", fi.Size(), expectedSize)
  3752. }
  3753. }
  3754. return err
  3755. }
  3756. func sftpUploadNonBlocking(localSourcePath string, remoteDestPath string, expectedSize int64, client *sftp.Client) <-chan error {
  3757. c := make(chan error)
  3758. go func() {
  3759. c <- sftpUploadFile(localSourcePath, remoteDestPath, expectedSize, client)
  3760. }()
  3761. return c
  3762. }
  3763. func sftpDownloadNonBlocking(remoteSourcePath string, localDestPath string, expectedSize int64, client *sftp.Client) <-chan error {
  3764. c := make(chan error)
  3765. go func() {
  3766. c <- sftpDownloadFile(remoteSourcePath, localDestPath, expectedSize, client)
  3767. }()
  3768. return c
  3769. }
  3770. func scpUpload(localPath, remotePath string, preserveTime, remoteToRemote bool) error {
  3771. cmd := getScpUploadCommand(localPath, remotePath, preserveTime, remoteToRemote)
  3772. return cmd.Run()
  3773. }
  3774. func scpDownload(localPath, remotePath string, preserveTime, recursive bool) error {
  3775. cmd := getScpDownloadCommand(localPath, remotePath, preserveTime, recursive)
  3776. return cmd.Run()
  3777. }
  3778. func getScpDownloadCommand(localPath, remotePath string, preserveTime, recursive bool) *exec.Cmd {
  3779. var args []string
  3780. if preserveTime {
  3781. args = append(args, "-p")
  3782. }
  3783. if recursive {
  3784. args = append(args, "-r")
  3785. }
  3786. args = append(args, "-P")
  3787. args = append(args, "2022")
  3788. args = append(args, "-o")
  3789. args = append(args, "StrictHostKeyChecking=no")
  3790. args = append(args, "-i")
  3791. args = append(args, privateKeyPath)
  3792. args = append(args, remotePath)
  3793. args = append(args, localPath)
  3794. return exec.Command(scpPath, args...)
  3795. }
  3796. func getScpUploadCommand(localPath, remotePath string, preserveTime, remoteToRemote bool) *exec.Cmd {
  3797. var args []string
  3798. if remoteToRemote {
  3799. args = append(args, "-3")
  3800. }
  3801. if preserveTime {
  3802. args = append(args, "-p")
  3803. }
  3804. fi, err := os.Stat(localPath)
  3805. if err == nil {
  3806. if fi.IsDir() {
  3807. args = append(args, "-r")
  3808. }
  3809. }
  3810. args = append(args, "-P")
  3811. args = append(args, "2022")
  3812. args = append(args, "-o")
  3813. args = append(args, "StrictHostKeyChecking=no")
  3814. args = append(args, "-i")
  3815. args = append(args, privateKeyPath)
  3816. args = append(args, localPath)
  3817. args = append(args, remotePath)
  3818. return exec.Command(scpPath, args...)
  3819. }
  3820. func computeHashForFile(hasher hash.Hash, path string) (string, error) {
  3821. hash := ""
  3822. f, err := os.Open(path)
  3823. if err != nil {
  3824. return hash, err
  3825. }
  3826. defer f.Close()
  3827. _, err = io.Copy(hasher, f)
  3828. if err == nil {
  3829. hash = fmt.Sprintf("%x", hasher.Sum(nil))
  3830. }
  3831. return hash, err
  3832. }
  3833. func waitForNoActiveTransfer() {
  3834. for len(sftpd.GetConnectionsStats()) > 0 {
  3835. time.Sleep(100 * time.Millisecond)
  3836. }
  3837. }
  3838. func waitForActiveTransfer() {
  3839. stats := sftpd.GetConnectionsStats()
  3840. for len(stats) < 1 {
  3841. stats = sftpd.GetConnectionsStats()
  3842. }
  3843. activeTransferFound := false
  3844. for !activeTransferFound {
  3845. stats = sftpd.GetConnectionsStats()
  3846. if len(stats) == 0 {
  3847. break
  3848. }
  3849. for _, stat := range stats {
  3850. if len(stat.Transfers) > 0 {
  3851. activeTransferFound = true
  3852. }
  3853. }
  3854. }
  3855. }
  3856. func waitQuotaScans() error {
  3857. time.Sleep(100 * time.Millisecond)
  3858. scans, _, err := httpd.GetQuotaScans(http.StatusOK)
  3859. if err != nil {
  3860. return err
  3861. }
  3862. for len(scans) > 0 {
  3863. time.Sleep(100 * time.Millisecond)
  3864. scans, _, err = httpd.GetQuotaScans(http.StatusOK)
  3865. if err != nil {
  3866. return err
  3867. }
  3868. }
  3869. return nil
  3870. }
  3871. func initGitRepo(path string) ([]byte, error) {
  3872. os.MkdirAll(path, 0777)
  3873. args := []string{"init", "--bare"}
  3874. cmd := exec.Command(gitPath, args...)
  3875. cmd.Dir = path
  3876. return cmd.CombinedOutput()
  3877. }
  3878. func pushToGitRepo(repoPath string) ([]byte, error) {
  3879. cmd := exec.Command(gitPath, "push")
  3880. cmd.Dir = repoPath
  3881. cmd.Env = append(os.Environ(),
  3882. fmt.Sprintf("GIT_SSH=%v", gitWrapPath))
  3883. return cmd.CombinedOutput()
  3884. }
  3885. func cloneGitRepo(basePath, remotePath, username string) ([]byte, error) {
  3886. remoteUrl := fmt.Sprintf("ssh://%[email protected]:2022%v", username, remotePath)
  3887. args := []string{"clone", remoteUrl}
  3888. cmd := exec.Command(gitPath, args...)
  3889. cmd.Dir = basePath
  3890. cmd.Env = append(os.Environ(),
  3891. fmt.Sprintf("GIT_SSH=%v", gitWrapPath))
  3892. return cmd.CombinedOutput()
  3893. }
  3894. func addFileToGitRepo(repoPath string, fileSize int64) ([]byte, error) {
  3895. path := filepath.Join(repoPath, "test")
  3896. err := createTestFile(path, fileSize)
  3897. if err != nil {
  3898. return []byte(""), err
  3899. }
  3900. cmd := exec.Command(gitPath, "config", "user.email", "[email protected]")
  3901. cmd.Dir = repoPath
  3902. out, err := cmd.CombinedOutput()
  3903. if err != nil {
  3904. return out, err
  3905. }
  3906. cmd = exec.Command(gitPath, "config", "user.name", "testuser")
  3907. cmd.Dir = repoPath
  3908. out, err = cmd.CombinedOutput()
  3909. if err != nil {
  3910. return out, err
  3911. }
  3912. cmd = exec.Command(gitPath, "add", "test")
  3913. cmd.Dir = repoPath
  3914. out, err = cmd.CombinedOutput()
  3915. if err != nil {
  3916. return out, err
  3917. }
  3918. cmd = exec.Command(gitPath, "commit", "-am", "test")
  3919. cmd.Dir = repoPath
  3920. return cmd.CombinedOutput()
  3921. }
  3922. func printLatestLogs(maxNumberOfLines int) {
  3923. var lines []string
  3924. f, err := os.Open(logFilePath)
  3925. if err != nil {
  3926. return
  3927. }
  3928. defer f.Close()
  3929. scanner := bufio.NewScanner(f)
  3930. for scanner.Scan() {
  3931. lines = append(lines, scanner.Text()+"\r\n")
  3932. for len(lines) > maxNumberOfLines {
  3933. lines = lines[1:]
  3934. }
  3935. }
  3936. if scanner.Err() != nil {
  3937. logger.WarnToConsole("Unable to print latest logs: %v", scanner.Err())
  3938. return
  3939. }
  3940. for _, line := range lines {
  3941. logger.DebugToConsole(line)
  3942. }
  3943. }