internal_test.go 58 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629
  1. // Copyright (C) 2019-2022 Nicola Murino
  2. //
  3. // This program is free software: you can redistribute it and/or modify
  4. // it under the terms of the GNU Affero General Public License as published
  5. // by the Free Software Foundation, version 3.
  6. //
  7. // This program is distributed in the hope that it will be useful,
  8. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  9. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  10. // GNU Affero General Public License for more details.
  11. //
  12. // You should have received a copy of the GNU Affero General Public License
  13. // along with this program. If not, see <https://www.gnu.org/licenses/>.
  14. package webdavd
  15. import (
  16. "context"
  17. "crypto/tls"
  18. "crypto/x509"
  19. "encoding/xml"
  20. "errors"
  21. "fmt"
  22. "io"
  23. "net/http"
  24. "net/http/httptest"
  25. "os"
  26. "path"
  27. "path/filepath"
  28. "runtime"
  29. "testing"
  30. "time"
  31. "github.com/eikenb/pipeat"
  32. "github.com/sftpgo/sdk"
  33. "github.com/stretchr/testify/assert"
  34. "golang.org/x/net/webdav"
  35. "github.com/drakkan/sftpgo/v2/internal/common"
  36. "github.com/drakkan/sftpgo/v2/internal/dataprovider"
  37. "github.com/drakkan/sftpgo/v2/internal/kms"
  38. "github.com/drakkan/sftpgo/v2/internal/util"
  39. "github.com/drakkan/sftpgo/v2/internal/vfs"
  40. )
  41. const (
  42. testFile = "test_dav_file"
  43. webDavCert = `-----BEGIN CERTIFICATE-----
  44. MIICHTCCAaKgAwIBAgIUHnqw7QnB1Bj9oUsNpdb+ZkFPOxMwCgYIKoZIzj0EAwIw
  45. RTELMAkGA1UEBhMCQVUxEzARBgNVBAgMClNvbWUtU3RhdGUxITAfBgNVBAoMGElu
  46. dGVybmV0IFdpZGdpdHMgUHR5IEx0ZDAeFw0yMDAyMDQwOTUzMDRaFw0zMDAyMDEw
  47. OTUzMDRaMEUxCzAJBgNVBAYTAkFVMRMwEQYDVQQIDApTb21lLVN0YXRlMSEwHwYD
  48. VQQKDBhJbnRlcm5ldCBXaWRnaXRzIFB0eSBMdGQwdjAQBgcqhkjOPQIBBgUrgQQA
  49. IgNiAARCjRMqJ85rzMC998X5z761nJ+xL3bkmGVqWvrJ51t5OxV0v25NsOgR82CA
  50. NXUgvhVYs7vNFN+jxtb2aj6Xg+/2G/BNxkaFspIVCzgWkxiz7XE4lgUwX44FCXZM
  51. 3+JeUbKjUzBRMB0GA1UdDgQWBBRhLw+/o3+Z02MI/d4tmaMui9W16jAfBgNVHSME
  52. GDAWgBRhLw+/o3+Z02MI/d4tmaMui9W16jAPBgNVHRMBAf8EBTADAQH/MAoGCCqG
  53. SM49BAMCA2kAMGYCMQDqLt2lm8mE+tGgtjDmtFgdOcI72HSbRQ74D5rYTzgST1rY
  54. /8wTi5xl8TiFUyLMUsICMQC5ViVxdXbhuG7gX6yEqSkMKZICHpO8hqFwOD/uaFVI
  55. dV4vKmHUzwK/eIx+8Ay3neE=
  56. -----END CERTIFICATE-----`
  57. webDavKey = `-----BEGIN EC PARAMETERS-----
  58. BgUrgQQAIg==
  59. -----END EC PARAMETERS-----
  60. -----BEGIN EC PRIVATE KEY-----
  61. MIGkAgEBBDCfMNsN6miEE3rVyUPwElfiJSWaR5huPCzUenZOfJT04GAcQdWvEju3
  62. UM2lmBLIXpGgBwYFK4EEACKhZANiAARCjRMqJ85rzMC998X5z761nJ+xL3bkmGVq
  63. WvrJ51t5OxV0v25NsOgR82CANXUgvhVYs7vNFN+jxtb2aj6Xg+/2G/BNxkaFspIV
  64. CzgWkxiz7XE4lgUwX44FCXZM3+JeUbI=
  65. -----END EC PRIVATE KEY-----`
  66. caCRT = `-----BEGIN CERTIFICATE-----
  67. MIIE5jCCAs6gAwIBAgIBATANBgkqhkiG9w0BAQsFADATMREwDwYDVQQDEwhDZXJ0
  68. QXV0aDAeFw0yMTAxMDIyMTIwNTVaFw0yMjA3MDIyMTMwNTJaMBMxETAPBgNVBAMT
  69. CENlcnRBdXRoMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEA4Tiho5xW
  70. AC15JRkMwfp3/TJwI2As7MY5dele5cmdr5bHAE+sRKqC+Ti88OJWCV5saoyax/1S
  71. CjxJlQMZMl169P1QYJskKjdG2sdv6RLWLMgwSNRRjxp/Bw9dHdiEb9MjLgu28Jro
  72. 9peQkHcRHeMf5hM9WvlIJGrdzbC4hUehmqggcqgARainBkYjf0SwuWxHeu4nMqkp
  73. Ak5tcSTLCjHfEFHZ9Te0TIPG5YkWocQKyeLgu4lvuU+DD2W2lym+YVUtRMGs1Env
  74. k7p+N0DcGU26qfzZ2sF5ZXkqm7dBsGQB9pIxwc2Q8T1dCIyP9OQCKVILdc5aVFf1
  75. cryQFHYzYNNZXFlIBims5VV5Mgfp8ESHQSue+v6n6ykecLEyKt1F1Y/MWY/nWUSI
  76. 8zdq83jdBAZVjo9MSthxVn57/06s/hQca65IpcTZV2gX0a+eRlAVqaRbAhL3LaZe
  77. bYsW3WHKoUOftwemuep3nL51TzlXZVL7Oz/ClGaEOsnGG9KFO6jh+W768qC0zLQI
  78. CdE7v2Zex98sZteHCg9fGJHIaYoF0aJG5P3WI5oZf2fy7UIYN9ADLFZiorCXAZEh
  79. CSU6mDoRViZ4RGR9GZxbDZ9KYn7O8M/KCR72bkQg73TlMsk1zSXEw0MKLUjtsw6c
  80. rZ0Jt8t3sRatHO3JrYHALMt9vZfyNCZp0IsCAwEAAaNFMEMwDgYDVR0PAQH/BAQD
  81. AgEGMBIGA1UdEwEB/wQIMAYBAf8CAQAwHQYDVR0OBBYEFO1yCNAGr/zQTJIi8lw3
  82. w5OiuBvMMA0GCSqGSIb3DQEBCwUAA4ICAQA6gCNuM7r8mnx674dm31GxBjQy5ZwB
  83. 7CxDzYEvL/oiZ3Tv3HlPfN2LAAsJUfGnghh9DOytenL2CTZWjl/emP5eijzmlP+9
  84. zva5I6CIMCf/eDDVsRdO244t0o4uG7+At0IgSDM3bpVaVb4RHZNjEziYChsEYY8d
  85. HK6iwuRSvFniV6yhR/Vj1Ymi9yZ5xclqseLXiQnUB0PkfIk23+7s42cXB16653fH
  86. O/FsPyKBLiKJArizLYQc12aP3QOrYoYD9+fAzIIzew7A5C0aanZCGzkuFpO6TRlD
  87. Tb7ry9Gf0DfPpCgxraH8tOcmnqp/ka3hjqo/SRnnTk0IFrmmLdarJvjD46rKwBo4
  88. MjyAIR1mQ5j8GTlSFBmSgETOQ/EYvO3FPLmra1Fh7L+DvaVzTpqI9fG3TuyyY+Ri
  89. Fby4ycTOGSZOe5Fh8lqkX5Y47mCUJ3zHzOA1vUJy2eTlMRGpu47Eb1++Vm6EzPUP
  90. 2EF5aD+zwcssh+atZvQbwxpgVqVcyLt91RSkKkmZQslh0rnlTb68yxvUnD3zw7So
  91. o6TAf9UvwVMEvdLT9NnFd6hwi2jcNte/h538GJwXeBb8EkfpqLKpTKyicnOdkamZ
  92. 7E9zY8SHNRYMwB9coQ/W8NvufbCgkvOoLyMXk5edbXofXl3PhNGOlraWbghBnzf5
  93. r3rwjFsQOoZotA==
  94. -----END CERTIFICATE-----`
  95. caKey = `-----BEGIN RSA PRIVATE KEY-----
  96. MIIJKQIBAAKCAgEA4Tiho5xWAC15JRkMwfp3/TJwI2As7MY5dele5cmdr5bHAE+s
  97. RKqC+Ti88OJWCV5saoyax/1SCjxJlQMZMl169P1QYJskKjdG2sdv6RLWLMgwSNRR
  98. jxp/Bw9dHdiEb9MjLgu28Jro9peQkHcRHeMf5hM9WvlIJGrdzbC4hUehmqggcqgA
  99. RainBkYjf0SwuWxHeu4nMqkpAk5tcSTLCjHfEFHZ9Te0TIPG5YkWocQKyeLgu4lv
  100. uU+DD2W2lym+YVUtRMGs1Envk7p+N0DcGU26qfzZ2sF5ZXkqm7dBsGQB9pIxwc2Q
  101. 8T1dCIyP9OQCKVILdc5aVFf1cryQFHYzYNNZXFlIBims5VV5Mgfp8ESHQSue+v6n
  102. 6ykecLEyKt1F1Y/MWY/nWUSI8zdq83jdBAZVjo9MSthxVn57/06s/hQca65IpcTZ
  103. V2gX0a+eRlAVqaRbAhL3LaZebYsW3WHKoUOftwemuep3nL51TzlXZVL7Oz/ClGaE
  104. OsnGG9KFO6jh+W768qC0zLQICdE7v2Zex98sZteHCg9fGJHIaYoF0aJG5P3WI5oZ
  105. f2fy7UIYN9ADLFZiorCXAZEhCSU6mDoRViZ4RGR9GZxbDZ9KYn7O8M/KCR72bkQg
  106. 73TlMsk1zSXEw0MKLUjtsw6crZ0Jt8t3sRatHO3JrYHALMt9vZfyNCZp0IsCAwEA
  107. AQKCAgAV+ElERYbaI5VyufvVnFJCH75ypPoc6sVGLEq2jbFVJJcq/5qlZCC8oP1F
  108. Xj7YUR6wUiDzK1Hqb7EZ2SCHGjlZVrCVi+y+NYAy7UuMZ+r+mVSkdhmypPoJPUVv
  109. GOTqZ6VB46Cn3eSl0WknvoWr7bD555yPmEuiSc5zNy74yWEJTidEKAFGyknowcTK
  110. sG+w1tAuPLcUKQ44DGB+rgEkcHL7C5EAa7upzx0C3RmZFB+dTAVyJdkBMbFuOhTS
  111. sB7DLeTplR7/4mp9da7EQw51ZXC1DlZOEZt++4/desXsqATNAbva1OuzrLG7mMKe
  112. N/PCBh/aERQcsCvgUmaXqGQgqN1Jhw8kbXnjZnVd9iE7TAh7ki3VqNy1OMgTwOex
  113. bBYWaCqHuDYIxCjeW0qLJcn0cKQ13FVYrxgInf4Jp82SQht5b/zLL3IRZEyKcLJF
  114. kL6g1wlmTUTUX0z8eZzlM0ZCrqtExjgElMO/rV971nyNV5WU8Og3NmE8/slqMrmJ
  115. DlrQr9q0WJsDKj1IMe46EUM6ix7bbxC5NIfJ96dgdxZDn6ghjca6iZYqqUACvmUj
  116. cq08s3R4Ouw9/87kn11wwGBx2yDueCwrjKEGc0RKjweGbwu0nBxOrkJ8JXz6bAv7
  117. 1OKfYaX3afI9B8x4uaiuRs38oBQlg9uAYFfl4HNBPuQikGLmsQKCAQEA8VjFOsaz
  118. y6NMZzKXi7WZ48uu3ed5x3Kf6RyDr1WvQ1jkBMv9b6b8Gp1CRnPqviRBto9L8QAg
  119. bCXZTqnXzn//brskmW8IZgqjAlf89AWa53piucu9/hgidrHRZobs5gTqev28uJdc
  120. zcuw1g8c3nCpY9WeTjHODzX5NXYRLFpkazLfYa6c8Q9jZR4KKrpdM+66fxL0JlOd
  121. 7dN0oQtEqEAugsd3cwkZgvWhY4oM7FGErrZoDLy273ZdJzi/vU+dThyVzfD8Ab8u
  122. VxxuobVMT/S608zbe+uaiUdov5s96OkCl87403UNKJBH+6LNb3rjBBLE9NPN5ET9
  123. JLQMrYd+zj8jQwKCAQEA7uU5I9MOufo9bIgJqjY4Ie1+Ex9DZEMUYFAvGNCJCVcS
  124. mwOdGF8AWzIavTLACmEDJO7t/OrBdoo4L7IEsCNjgA3WiIwIMiWUVqveAGUMEXr6
  125. TRI5EolV6FTqqIP6AS+BAeBq7G1ELgsTrWNHh11rW3+3kBMuOCn77PUQ8WHwcq/r
  126. teZcZn4Ewcr6P7cBODgVvnBPhe/J8xHS0HFVCeS1CvaiNYgees5yA80Apo9IPjDJ
  127. YWawLjmH5wUBI5yDFVp067wjqJnoKPSoKwWkZXqUk+zgFXx5KT0gh/c5yh1frASp
  128. q6oaYnHEVC5qj2SpT1GFLonTcrQUXiSkiUudvNu1GQKCAQEAmko+5GFtRe0ihgLQ
  129. 4S76r6diJli6AKil1Fg3U1r6zZpBQ1PJtJxTJQyN9w5Z7q6tF/GqAesrzxevQdvQ
  130. rCImAPtA3ZofC2UXawMnIjWHHx6diNvYnV1+gtUQ4nO1dSOFZ5VZFcUmPiZO6boF
  131. oaryj3FcX+71JcJCjEvrlKhA9Es0hXUkvfMxfs5if4he1zlyHpTWYr4oA4egUugq
  132. P0mwskikc3VIyvEO+NyjgFxo72yLPkFSzemkidN8uKDyFqKtnlfGM7OuA2CY1WZa
  133. 3+67lXWshx9KzyJIs92iCYkU8EoPxtdYzyrV6efdX7x27v60zTOut5TnJJS6WiF6
  134. Do5MkwKCAQAxoR9IyP0DN/BwzqYrXU42Bi+t603F04W1KJNQNWpyrUspNwv41yus
  135. xnD1o0hwH41Wq+h3JZIBfV+E0RfWO9Pc84MBJQ5C1LnHc7cQH+3s575+Km3+4tcd
  136. CB8j2R8kBeloKWYtLdn/Mr/ownpGreqyvIq2/LUaZ+Z1aMgXTYB1YwS16mCBzmZQ
  137. mEl62RsAwe4KfSyYJ6OtwqMoOJMxFfliiLBULK4gVykqjvk2oQeiG+KKQJoTUFJi
  138. dRCyhD5bPkqR+qjxyt+HOqSBI4/uoROi05AOBqjpH1DVzk+MJKQOiX1yM0l98CKY
  139. Vng+x+vAla/0Zh+ucajVkgk4mKPxazdpAoIBAQC17vWk4KYJpF2RC3pKPcQ0PdiX
  140. bN35YNlvyhkYlSfDNdyH3aDrGiycUyW2mMXUgEDFsLRxHMTL+zPC6efqO6sTAJDY
  141. cBptsW4drW/qo8NTx3dNOisLkW+mGGJOR/w157hREFr29ymCVMYu/Z7fVWIeSpCq
  142. p3u8YX8WTljrxwSczlGjvpM7uJx3SfYRM4TUoy+8wU8bK74LywLa5f60bQY6Dye0
  143. Gqd9O6OoPfgcQlwjC5MiAofeqwPJvU0hQOPoehZyNLAmOCWXTYWaTP7lxO1r6+NE
  144. M3hGYqW3W8Ixua71OskCypBZg/HVlIP/lzjRzdx+VOB2hbWVth2Iup/Z1egW
  145. -----END RSA PRIVATE KEY-----`
  146. caCRL = `-----BEGIN X509 CRL-----
  147. MIICpzCBkAIBATANBgkqhkiG9w0BAQsFADATMREwDwYDVQQDEwhDZXJ0QXV0aBcN
  148. MjEwMTAyMjEzNDA1WhcNMjMwMTAyMjEzNDA1WjAkMCICEQC+l04DbHWMyC3fG09k
  149. VXf+Fw0yMTAxMDIyMTM0MDVaoCMwITAfBgNVHSMEGDAWgBTtcgjQBq/80EySIvJc
  150. N8OTorgbzDANBgkqhkiG9w0BAQsFAAOCAgEAEJ7z+uNc8sqtxlOhSdTGDzX/xput
  151. E857kFQkSlMnU2whQ8c+XpYrBLA5vIZJNSSwohTpM4+zVBX/bJpmu3wqqaArRO9/
  152. YcW5mQk9Anvb4WjQW1cHmtNapMTzoC9AiYt/OWPfy+P6JCgCr4Hy6LgQyIRL6bM9
  153. VYTalolOm1qa4Y5cIeT7iHq/91mfaqo8/6MYRjLl8DOTROpmw8OS9bCXkzGKdCat
  154. AbAzwkQUSauyoCQ10rpX+Y64w9ng3g4Dr20aCqPf5osaqplEJ2HTK8ljDTidlslv
  155. 9anQj8ax3Su89vI8+hK+YbfVQwrThabgdSjQsn+veyx8GlP8WwHLAQ379KjZjWg+
  156. OlOSwBeU1vTdP0QcB8X5C2gVujAyuQekbaV86xzIBOj7vZdfHZ6ee30TZ2FKiMyg
  157. 7/N2OqW0w77ChsjB4MSHJCfuTgIeg62GzuZXLM+Q2Z9LBdtm4Byg+sm/P52adOEg
  158. gVb2Zf4KSvsAmA0PIBlu449/QXUFcMxzLFy7mwTeZj2B4Ln0Hm0szV9f9R8MwMtB
  159. SyLYxVH+mgqaR6Jkk22Q/yYyLPaELfafX5gp/AIXG8n0zxfVaTvK3auSgb1Q6ZLS
  160. 5QH9dSIsmZHlPq7GoSXmKpMdjUL8eaky/IMteioyXgsBiATzl5L2dsw6MTX3MDF0
  161. QbDK+MzhmbKfDxs=
  162. -----END X509 CRL-----`
  163. client1Crt = `-----BEGIN CERTIFICATE-----
  164. MIIEITCCAgmgAwIBAgIRAIppZHoj1hM80D7WzTEKLuAwDQYJKoZIhvcNAQELBQAw
  165. EzERMA8GA1UEAxMIQ2VydEF1dGgwHhcNMjEwMTAyMjEyMzEwWhcNMjIwNzAyMjEz
  166. MDUxWjASMRAwDgYDVQQDEwdjbGllbnQxMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A
  167. MIIBCgKCAQEAoKbYY9MdF2kF/nhBESIiZTdVYtA8XL9xrIZyDj9EnCiTxHiVbJtH
  168. XVwszqSl5TRrotPmnmAQcX3r8OCk+z+RQZ0QQj257P3kG6q4rNnOcWCS5xEd20jP
  169. yhQ3m+hMGfZsotNTQze1ochuQgLUN6IPyPxZkH22ia3jX4iu1eo/QxeLYHj1UHw4
  170. 3Cii9yE+j5kPUC21xmnrGKdUrB55NYLXHx6yTIqYR5znSOVB8oJi18/hwdZmH859
  171. DHhm0Hx1HrS+jbjI3+CMorZJ3WUyNf+CkiVLD3xYutPbxzEpwiqkG/XYzLH0habT
  172. cDcILo18n+o3jvem2KWBrDhyairjIDscwQIDAQABo3EwbzAOBgNVHQ8BAf8EBAMC
  173. A7gwHQYDVR0lBBYwFAYIKwYBBQUHAwEGCCsGAQUFBwMCMB0GA1UdDgQWBBSJ5GIv
  174. zIrE4ZSQt2+CGblKTDswizAfBgNVHSMEGDAWgBTtcgjQBq/80EySIvJcN8OTorgb
  175. zDANBgkqhkiG9w0BAQsFAAOCAgEALh4f5GhvNYNou0Ab04iQBbLEdOu2RlbK1B5n
  176. K9P/umYenBHMY/z6HT3+6tpcHsDuqE8UVdq3f3Gh4S2Gu9m8PRitT+cJ3gdo9Plm
  177. 3rD4ufn/s6rGg3ppydXcedm17492tbccUDWOBZw3IO/ASVq13WPgT0/Kev7cPq0k
  178. sSdSNhVeXqx8Myc2/d+8GYyzbul2Kpfa7h9i24sK49E9ftnSmsIvngONo08eT1T0
  179. 3wAOyK2981LIsHaAWcneShKFLDB6LeXIT9oitOYhiykhFlBZ4M1GNlSNfhQ8IIQP
  180. xbqMNXCLkW4/BtLhGEEcg0QVso6Kudl9rzgTfQknrdF7pHp6rS46wYUjoSyIY6dl
  181. oLmnoAVJX36J3QPWelePI9e07X2wrTfiZWewwgw3KNRWjd6/zfPLe7GoqXnK1S2z
  182. PT8qMfCaTwKTtUkzXuTFvQ8bAo2My/mS8FOcpkt2oQWeOsADHAUX7fz5BCoa2DL3
  183. k/7Mh4gVT+JYZEoTwCFuYHgMWFWe98naqHi9lB4yR981p1QgXgxO7qBeipagKY1F
  184. LlH1iwXUqZ3MZnkNA+4e1Fglsw3sa/rC+L98HnznJ/YbTfQbCP6aQ1qcOymrjMud
  185. 7MrFwqZjtd/SK4Qx1VpK6jGEAtPgWBTUS3p9ayg6lqjMBjsmySWfvRsDQbq6P5Ct
  186. O/e3EH8=
  187. -----END CERTIFICATE-----`
  188. client1Key = `-----BEGIN RSA PRIVATE KEY-----
  189. MIIEpAIBAAKCAQEAoKbYY9MdF2kF/nhBESIiZTdVYtA8XL9xrIZyDj9EnCiTxHiV
  190. bJtHXVwszqSl5TRrotPmnmAQcX3r8OCk+z+RQZ0QQj257P3kG6q4rNnOcWCS5xEd
  191. 20jPyhQ3m+hMGfZsotNTQze1ochuQgLUN6IPyPxZkH22ia3jX4iu1eo/QxeLYHj1
  192. UHw43Cii9yE+j5kPUC21xmnrGKdUrB55NYLXHx6yTIqYR5znSOVB8oJi18/hwdZm
  193. H859DHhm0Hx1HrS+jbjI3+CMorZJ3WUyNf+CkiVLD3xYutPbxzEpwiqkG/XYzLH0
  194. habTcDcILo18n+o3jvem2KWBrDhyairjIDscwQIDAQABAoIBAEBSjVFqtbsp0byR
  195. aXvyrtLX1Ng7h++at2jca85Ihq//jyqbHTje8zPuNAKI6eNbmb0YGr5OuEa4pD9N
  196. ssDmMsKSoG/lRwwcm7h4InkSvBWpFShvMgUaohfHAHzsBYxfnh+TfULsi0y7c2n6
  197. t/2OZcOTRkkUDIITnXYiw93ibHHv2Mv2bBDu35kGrcK+c2dN5IL5ZjTjMRpbJTe2
  198. 44RBJbdTxHBVSgoGBnugF+s2aEma6Ehsj70oyfoVpM6Aed5kGge0A5zA1JO7WCn9
  199. Ay/DzlULRXHjJIoRWd2NKvx5n3FNppUc9vJh2plRHalRooZ2+MjSf8HmXlvG2Hpb
  200. ScvmWgECgYEA1G+A/2KnxWsr/7uWIJ7ClcGCiNLdk17Pv3DZ3G4qUsU2ITftfIbb
  201. tU0Q/b19na1IY8Pjy9ptP7t74/hF5kky97cf1FA8F+nMj/k4+wO8QDI8OJfzVzh9
  202. PwielA5vbE+xmvis5Hdp8/od1Yrc/rPSy2TKtPFhvsqXjqoUmOAjDP8CgYEAwZjH
  203. 9dt1sc2lx/rMxihlWEzQ3JPswKW9/LJAmbRBoSWF9FGNjbX7uhWtXRKJkzb8ZAwa
  204. 88azluNo2oftbDD/+jw8b2cDgaJHlLAkSD4O1D1RthW7/LKD15qZ/oFsRb13NV85
  205. ZNKtwslXGbfVNyGKUVFm7fVA8vBAOUey+LKDFj8CgYEAg8WWstOzVdYguMTXXuyb
  206. ruEV42FJaDyLiSirOvxq7GTAKuLSQUg1yMRBIeQEo2X1XU0JZE3dLodRVhuO4EXP
  207. g7Dn4X7Th9HSvgvNuIacowWGLWSz4Qp9RjhGhXhezUSx2nseY6le46PmFavJYYSR
  208. 4PBofMyt4PcyA6Cknh+KHmkCgYEAnTriG7ETE0a7v4DXUpB4TpCEiMCy5Xs2o8Z5
  209. ZNva+W+qLVUWq+MDAIyechqeFSvxK6gRM69LJ96lx+XhU58wJiFJzAhT9rK/g+jS
  210. bsHH9WOfu0xHkuHA5hgvvV2Le9B2wqgFyva4HJy82qxMxCu/VG/SMqyfBS9OWbb7
  211. ibQhdq0CgYAl53LUWZsFSZIth1vux2LVOsI8C3X1oiXDGpnrdlQ+K7z57hq5EsRq
  212. GC+INxwXbvKNqp5h0z2MvmKYPDlGVTgw8f8JjM7TkN17ERLcydhdRrMONUryZpo8
  213. 1xTob+8blyJgfxZUIAKbMbMbIiU0WAF0rfD/eJJwS4htOW/Hfv4TGA==
  214. -----END RSA PRIVATE KEY-----`
  215. // client 2 crt is revoked
  216. client2Crt = `-----BEGIN CERTIFICATE-----
  217. MIIEITCCAgmgAwIBAgIRAL6XTgNsdYzILd8bT2RVd/4wDQYJKoZIhvcNAQELBQAw
  218. EzERMA8GA1UEAxMIQ2VydEF1dGgwHhcNMjEwMTAyMjEyMzIwWhcNMjIwNzAyMjEz
  219. MDUxWjASMRAwDgYDVQQDEwdjbGllbnQyMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A
  220. MIIBCgKCAQEA6xjW5KQR3/OFQtV5M75WINqQ4AzXSu6DhSz/yumaaQZP/UxY+6hi
  221. jcrFzGo9MMie/Sza8DhkXOFAl2BelUubrOeB2cl+/Gr8OCyRi2Gv6j3zCsuN/4jQ
  222. tNaoez/IbkDvI3l/ZpzBtnuNY2RiemGgHuORXHRVf3qVlsw+npBIRW5rM2HkO/xG
  223. oZjeBErWVu390Lyn+Gvk2TqQDnkutWnxUC60/zPlHhXZ4BwaFAekbSnjsSDB1YFM
  224. s8HwW4oBryoxdj3/+/qLrBHt75IdLw3T7/V1UDJQM3EvSQOr12w4egpldhtsC871
  225. nnBQZeY6qA5feffIwwg/6lJm70o6S6OX6wIDAQABo3EwbzAOBgNVHQ8BAf8EBAMC
  226. A7gwHQYDVR0lBBYwFAYIKwYBBQUHAwEGCCsGAQUFBwMCMB0GA1UdDgQWBBTB84v5
  227. t9HqhLhMODbn6oYkEQt3KzAfBgNVHSMEGDAWgBTtcgjQBq/80EySIvJcN8OTorgb
  228. zDANBgkqhkiG9w0BAQsFAAOCAgEALGtBCve5k8tToL3oLuXp/oSik6ovIB/zq4I/
  229. 4zNMYPU31+ZWz6aahysgx1JL1yqTa3Qm8o2tu52MbnV10dM7CIw7c/cYa+c+OPcG
  230. 5LF97kp13X+r2axy+CmwM86b4ILaDGs2Qyai6VB6k7oFUve+av5o7aUrNFpqGCJz
  231. HWdtHZSVA3JMATzy0TfWanwkzreqfdw7qH0yZ9bDURlBKAVWrqnCstva9jRuv+AI
  232. eqxr/4Ro986TFjJdoAP3Vr16CPg7/B6GA/KmsBWJrpeJdPWq4i2gpLKvYZoy89qD
  233. mUZf34RbzcCtV4NvV1DadGnt4us0nvLrvS5rL2+2uWD09kZYq9RbLkvgzF/cY0fz
  234. i7I1bi5XQ+alWe0uAk5ZZL/D+GTRYUX1AWwCqwJxmHrMxcskMyO9pXvLyuSWRDLo
  235. YNBrbX9nLcfJzVCp+X+9sntTHjs4l6Cw+fLepJIgtgqdCHtbhTiv68vSM6cgb4br
  236. 6n2xrXRKuioiWFOrTSRr+oalZh8dGJ/xvwY8IbWknZAvml9mf1VvfE7Ma5P777QM
  237. fsbYVTq0Y3R/5hIWsC3HA5z6MIM8L1oRe/YyhP3CTmrCHkVKyDOosGXpGz+JVcyo
  238. cfYkY5A3yFKB2HaCwZSfwFmRhxkrYWGEbHv3Cd9YkZs1J3hNhGFZyVMC9Uh0S85a
  239. 6zdDidU=
  240. -----END CERTIFICATE-----`
  241. client2Key = `-----BEGIN RSA PRIVATE KEY-----
  242. MIIEpAIBAAKCAQEA6xjW5KQR3/OFQtV5M75WINqQ4AzXSu6DhSz/yumaaQZP/UxY
  243. +6hijcrFzGo9MMie/Sza8DhkXOFAl2BelUubrOeB2cl+/Gr8OCyRi2Gv6j3zCsuN
  244. /4jQtNaoez/IbkDvI3l/ZpzBtnuNY2RiemGgHuORXHRVf3qVlsw+npBIRW5rM2Hk
  245. O/xGoZjeBErWVu390Lyn+Gvk2TqQDnkutWnxUC60/zPlHhXZ4BwaFAekbSnjsSDB
  246. 1YFMs8HwW4oBryoxdj3/+/qLrBHt75IdLw3T7/V1UDJQM3EvSQOr12w4egpldhts
  247. C871nnBQZeY6qA5feffIwwg/6lJm70o6S6OX6wIDAQABAoIBAFatstVb1KdQXsq0
  248. cFpui8zTKOUiduJOrDkWzTygAmlEhYtrccdfXu7OWz0x0lvBLDVGK3a0I/TGrAzj
  249. 4BuFY+FM/egxTVt9in6fmA3et4BS1OAfCryzUdfK6RV//8L+t+zJZ/qKQzWnugpy
  250. QYjDo8ifuMFwtvEoXizaIyBNLAhEp9hnrv+Tyi2O2gahPvCHsD48zkyZRCHYRstD
  251. NH5cIrwz9/RJgPO1KI+QsJE7Nh7stR0sbr+5TPU4fnsL2mNhMUF2TJrwIPrc1yp+
  252. YIUjdnh3SO88j4TQT3CIrWi8i4pOy6N0dcVn3gpCRGaqAKyS2ZYUj+yVtLO4KwxZ
  253. SZ1lNvECgYEA78BrF7f4ETfWSLcBQ3qxfLs7ibB6IYo2x25685FhZjD+zLXM1AKb
  254. FJHEXUm3mUYrFJK6AFEyOQnyGKBOLs3S6oTAswMPbTkkZeD1Y9O6uv0AHASLZnK6
  255. pC6ub0eSRF5LUyTQ55Jj8D7QsjXJueO8v+G5ihWhNSN9tB2UA+8NBmkCgYEA+weq
  256. cvoeMIEMBQHnNNLy35bwfqrceGyPIRBcUIvzQfY1vk7KW6DYOUzC7u+WUzy/hA52
  257. DjXVVhua2eMQ9qqtOav7djcMc2W9RbLowxvno7K5qiCss013MeWk64TCWy+WMp5A
  258. AVAtOliC3hMkIKqvR2poqn+IBTh1449agUJQqTMCgYEAu06IHGq1GraV6g9XpGF5
  259. wqoAlMzUTdnOfDabRilBf/YtSr+J++ThRcuwLvXFw7CnPZZ4TIEjDJ7xjj3HdxeE
  260. fYYjineMmNd40UNUU556F1ZLvJfsVKizmkuCKhwvcMx+asGrmA+tlmds4p3VMS50
  261. KzDtpKzLWlmU/p/RINWlRmkCgYBy0pHTn7aZZx2xWKqCDg+L2EXPGqZX6wgZDpu7
  262. OBifzlfM4ctL2CmvI/5yPmLbVgkgBWFYpKUdiujsyyEiQvWTUKhn7UwjqKDHtcsk
  263. G6p7xS+JswJrzX4885bZJ9Oi1AR2yM3sC9l0O7I4lDbNPmWIXBLeEhGMmcPKv/Kc
  264. 91Ff4wKBgQCF3ur+Vt0PSU0ucrPVHjCe7tqazm0LJaWbPXL1Aw0pzdM2EcNcW/MA
  265. w0kqpr7MgJ94qhXCBcVcfPuFN9fBOadM3UBj1B45Cz3pptoK+ScI8XKno6jvVK/p
  266. xr5cb9VBRBtB9aOKVfuRhpatAfS2Pzm2Htae9lFn7slGPUmu2hkjDw==
  267. -----END RSA PRIVATE KEY-----`
  268. )
  269. var (
  270. errWalkDir = errors.New("err walk dir")
  271. errWalkFile = errors.New("err walk file")
  272. )
  273. // MockOsFs mockable OsFs
  274. type MockOsFs struct {
  275. vfs.Fs
  276. err error
  277. isAtomicUploadSupported bool
  278. reader *pipeat.PipeReaderAt
  279. }
  280. // Name returns the name for the Fs implementation
  281. func (fs *MockOsFs) Name() string {
  282. return "mockOsFs"
  283. }
  284. // Open returns nil
  285. func (fs *MockOsFs) Open(name string, offset int64) (vfs.File, *pipeat.PipeReaderAt, func(), error) {
  286. return nil, fs.reader, nil, nil
  287. }
  288. // IsUploadResumeSupported returns true if resuming uploads is supported
  289. func (*MockOsFs) IsUploadResumeSupported() bool {
  290. return false
  291. }
  292. // IsAtomicUploadSupported returns true if atomic upload is supported
  293. func (fs *MockOsFs) IsAtomicUploadSupported() bool {
  294. return fs.isAtomicUploadSupported
  295. }
  296. // Remove removes the named file or (empty) directory.
  297. func (fs *MockOsFs) Remove(name string, isDir bool) error {
  298. if fs.err != nil {
  299. return fs.err
  300. }
  301. return os.Remove(name)
  302. }
  303. // Rename renames (moves) source to target
  304. func (fs *MockOsFs) Rename(source, target string) error {
  305. if fs.err != nil {
  306. return fs.err
  307. }
  308. return os.Rename(source, target)
  309. }
  310. // Walk returns a duplicate path for testing
  311. func (fs *MockOsFs) Walk(root string, walkFn filepath.WalkFunc) error {
  312. if fs.err == errWalkDir {
  313. walkFn("fsdpath", vfs.NewFileInfo("dpath", true, 0, time.Now(), false), nil) //nolint:errcheck
  314. walkFn("fsdpath", vfs.NewFileInfo("dpath", true, 0, time.Now(), false), nil) //nolint:errcheck
  315. return nil
  316. }
  317. walkFn("fsfpath", vfs.NewFileInfo("fpath", false, 0, time.Now(), false), nil) //nolint:errcheck
  318. return fs.err
  319. }
  320. // GetMimeType returns the content type
  321. func (fs *MockOsFs) GetMimeType(name string) (string, error) {
  322. return "application/custom-mime", nil
  323. }
  324. func newMockOsFs(err error, atomicUpload bool, connectionID, rootDir string, reader *pipeat.PipeReaderAt) vfs.Fs {
  325. return &MockOsFs{
  326. Fs: vfs.NewOsFs(connectionID, rootDir, ""),
  327. err: err,
  328. isAtomicUploadSupported: atomicUpload,
  329. reader: reader,
  330. }
  331. }
  332. func TestOrderDirsToRemove(t *testing.T) {
  333. user := dataprovider.User{}
  334. fs := vfs.NewOsFs("id", os.TempDir(), "")
  335. connection := &Connection{
  336. BaseConnection: common.NewBaseConnection(fs.ConnectionID(), common.ProtocolWebDAV, "", "", user),
  337. request: nil,
  338. }
  339. dirsToRemove := []objectMapping{}
  340. orderedDirs := connection.orderDirsToRemove(fs, dirsToRemove)
  341. assert.Equal(t, len(dirsToRemove), len(orderedDirs))
  342. dirsToRemove = []objectMapping{
  343. {
  344. fsPath: "dir1",
  345. virtualPath: "",
  346. },
  347. }
  348. orderedDirs = connection.orderDirsToRemove(fs, dirsToRemove)
  349. assert.Equal(t, len(dirsToRemove), len(orderedDirs))
  350. dirsToRemove = []objectMapping{
  351. {
  352. fsPath: "dir1",
  353. virtualPath: "",
  354. },
  355. {
  356. fsPath: "dir12",
  357. virtualPath: "",
  358. },
  359. {
  360. fsPath: filepath.Join("dir1", "a", "b"),
  361. virtualPath: "",
  362. },
  363. {
  364. fsPath: filepath.Join("dir1", "a"),
  365. virtualPath: "",
  366. },
  367. }
  368. orderedDirs = connection.orderDirsToRemove(fs, dirsToRemove)
  369. if assert.Equal(t, len(dirsToRemove), len(orderedDirs)) {
  370. assert.Equal(t, "dir12", orderedDirs[0].fsPath)
  371. assert.Equal(t, filepath.Join("dir1", "a", "b"), orderedDirs[1].fsPath)
  372. assert.Equal(t, filepath.Join("dir1", "a"), orderedDirs[2].fsPath)
  373. assert.Equal(t, "dir1", orderedDirs[3].fsPath)
  374. }
  375. }
  376. func TestUserInvalidParams(t *testing.T) {
  377. u := &dataprovider.User{
  378. BaseUser: sdk.BaseUser{
  379. Username: "username",
  380. HomeDir: "invalid",
  381. },
  382. }
  383. c := &Configuration{
  384. Bindings: []Binding{
  385. {
  386. Port: 9000,
  387. },
  388. },
  389. }
  390. server := webDavServer{
  391. config: c,
  392. binding: c.Bindings[0],
  393. }
  394. req, err := http.NewRequest(http.MethodGet, fmt.Sprintf("/%v", u.Username), nil)
  395. assert.NoError(t, err)
  396. _, err = server.validateUser(u, req, dataprovider.LoginMethodPassword)
  397. if assert.Error(t, err) {
  398. assert.EqualError(t, err, fmt.Sprintf("cannot login user with invalid home dir: %#v", u.HomeDir))
  399. }
  400. req.TLS = &tls.ConnectionState{}
  401. writeLog(req, http.StatusOK, nil)
  402. }
  403. func TestAllowedProxyUnixDomainSocket(t *testing.T) {
  404. b := Binding{
  405. Address: filepath.Join(os.TempDir(), "sock"),
  406. ProxyAllowed: []string{"127.0.0.1", "127.0.1.1"},
  407. }
  408. err := b.parseAllowedProxy()
  409. assert.NoError(t, err)
  410. if assert.Len(t, b.allowHeadersFrom, 1) {
  411. assert.True(t, b.allowHeadersFrom[0](nil))
  412. }
  413. }
  414. func TestRemoteAddress(t *testing.T) {
  415. remoteAddr1 := "100.100.100.100"
  416. remoteAddr2 := "172.172.172.172"
  417. c := &Configuration{
  418. Bindings: []Binding{
  419. {
  420. Port: 9000,
  421. ProxyAllowed: []string{remoteAddr2, "10.8.0.0/30"},
  422. },
  423. },
  424. }
  425. server := webDavServer{
  426. config: c,
  427. binding: c.Bindings[0],
  428. }
  429. err := server.binding.parseAllowedProxy()
  430. assert.NoError(t, err)
  431. req, err := http.NewRequest(http.MethodGet, "/", nil)
  432. assert.NoError(t, err)
  433. assert.Empty(t, req.RemoteAddr)
  434. trueClientIP := "True-Client-IP"
  435. cfConnectingIP := "CF-Connecting-IP"
  436. xff := "X-Forwarded-For"
  437. xRealIP := "X-Real-IP"
  438. req.Header.Set(trueClientIP, remoteAddr1)
  439. ip := util.GetRealIP(req, trueClientIP, 0)
  440. assert.Equal(t, remoteAddr1, ip)
  441. ip = util.GetRealIP(req, trueClientIP, 2)
  442. assert.Empty(t, ip)
  443. req.Header.Del(trueClientIP)
  444. req.Header.Set(cfConnectingIP, remoteAddr1)
  445. ip = util.GetRealIP(req, cfConnectingIP, 0)
  446. assert.Equal(t, remoteAddr1, ip)
  447. req.Header.Del(cfConnectingIP)
  448. req.Header.Set(xff, remoteAddr1)
  449. ip = util.GetRealIP(req, xff, 0)
  450. assert.Equal(t, remoteAddr1, ip)
  451. // this will be ignored, remoteAddr1 is not allowed to se this header
  452. req.Header.Set(xff, remoteAddr2)
  453. req.RemoteAddr = remoteAddr1
  454. ip = server.checkRemoteAddress(req)
  455. assert.Equal(t, remoteAddr1, ip)
  456. req.RemoteAddr = ""
  457. ip = server.checkRemoteAddress(req)
  458. assert.Empty(t, ip)
  459. req.Header.Set(xff, fmt.Sprintf("%v , %v", remoteAddr2, remoteAddr1))
  460. ip = util.GetRealIP(req, xff, 1)
  461. assert.Equal(t, remoteAddr2, ip)
  462. req.RemoteAddr = remoteAddr2
  463. req.Header.Set(xff, fmt.Sprintf("%v,%v", "12.34.56.78", "172.16.2.4"))
  464. server.binding.ClientIPHeaderDepth = 1
  465. server.binding.ClientIPProxyHeader = xff
  466. ip = server.checkRemoteAddress(req)
  467. assert.Equal(t, "12.34.56.78", ip)
  468. assert.Equal(t, ip, req.RemoteAddr)
  469. req.RemoteAddr = remoteAddr2
  470. req.Header.Set(xff, fmt.Sprintf("%v,%v", "12.34.56.79", "172.16.2.5"))
  471. server.binding.ClientIPHeaderDepth = 0
  472. ip = server.checkRemoteAddress(req)
  473. assert.Equal(t, "172.16.2.5", ip)
  474. assert.Equal(t, ip, req.RemoteAddr)
  475. req.RemoteAddr = "10.8.0.2"
  476. req.Header.Set(xff, remoteAddr1)
  477. ip = server.checkRemoteAddress(req)
  478. assert.Equal(t, remoteAddr1, ip)
  479. assert.Equal(t, ip, req.RemoteAddr)
  480. req.RemoteAddr = "10.8.0.3"
  481. req.Header.Set(xff, "not an ip")
  482. ip = server.checkRemoteAddress(req)
  483. assert.Equal(t, "10.8.0.3", ip)
  484. assert.Equal(t, ip, req.RemoteAddr)
  485. req.Header.Del(xff)
  486. req.RemoteAddr = ""
  487. req.Header.Set(xRealIP, remoteAddr1)
  488. ip = util.GetRealIP(req, "x-real-ip", 0)
  489. assert.Equal(t, remoteAddr1, ip)
  490. req.RemoteAddr = ""
  491. }
  492. func TestConnWithNilRequest(t *testing.T) {
  493. c := &Connection{}
  494. assert.Empty(t, c.GetClientVersion())
  495. assert.Empty(t, c.GetCommand())
  496. assert.Empty(t, c.GetRemoteAddress())
  497. }
  498. func TestResolvePathErrors(t *testing.T) {
  499. ctx := context.Background()
  500. user := dataprovider.User{
  501. BaseUser: sdk.BaseUser{
  502. HomeDir: "invalid",
  503. },
  504. }
  505. user.Permissions = make(map[string][]string)
  506. user.Permissions["/"] = []string{dataprovider.PermAny}
  507. fs := vfs.NewOsFs("connID", user.HomeDir, "")
  508. connection := &Connection{
  509. BaseConnection: common.NewBaseConnection(fs.ConnectionID(), common.ProtocolWebDAV, "", "", user),
  510. }
  511. err := connection.Mkdir(ctx, "", os.ModePerm)
  512. if assert.Error(t, err) {
  513. assert.EqualError(t, err, common.ErrGenericFailure.Error())
  514. }
  515. err = connection.Rename(ctx, "oldName", "newName")
  516. if assert.Error(t, err) {
  517. assert.EqualError(t, err, common.ErrGenericFailure.Error())
  518. }
  519. _, err = connection.Stat(ctx, "name")
  520. if assert.Error(t, err) {
  521. assert.EqualError(t, err, common.ErrGenericFailure.Error())
  522. }
  523. err = connection.RemoveAll(ctx, "")
  524. if assert.Error(t, err) {
  525. assert.EqualError(t, err, common.ErrGenericFailure.Error())
  526. }
  527. _, err = connection.OpenFile(ctx, "", 0, os.ModePerm)
  528. if assert.Error(t, err) {
  529. assert.EqualError(t, err, common.ErrGenericFailure.Error())
  530. }
  531. if runtime.GOOS != "windows" {
  532. user.HomeDir = filepath.Clean(os.TempDir())
  533. connection.User = user
  534. fs := vfs.NewOsFs("connID", connection.User.HomeDir, "")
  535. subDir := "sub"
  536. testTxtFile := "file.txt"
  537. err = os.MkdirAll(filepath.Join(os.TempDir(), subDir, subDir), os.ModePerm)
  538. assert.NoError(t, err)
  539. err = os.WriteFile(filepath.Join(os.TempDir(), subDir, subDir, testTxtFile), []byte("content"), os.ModePerm)
  540. assert.NoError(t, err)
  541. err = os.Chmod(filepath.Join(os.TempDir(), subDir, subDir), 0001)
  542. assert.NoError(t, err)
  543. err = os.WriteFile(filepath.Join(os.TempDir(), testTxtFile), []byte("test content"), os.ModePerm)
  544. assert.NoError(t, err)
  545. err = connection.Rename(ctx, testTxtFile, path.Join(subDir, subDir, testTxtFile))
  546. if assert.Error(t, err) {
  547. assert.EqualError(t, err, common.ErrPermissionDenied.Error())
  548. }
  549. _, err = connection.putFile(fs, filepath.Join(connection.User.HomeDir, subDir, subDir, testTxtFile),
  550. path.Join(subDir, subDir, testTxtFile))
  551. if assert.Error(t, err) {
  552. assert.EqualError(t, err, common.ErrPermissionDenied.Error())
  553. }
  554. err = os.Chmod(filepath.Join(os.TempDir(), subDir, subDir), os.ModePerm)
  555. assert.NoError(t, err)
  556. err = os.RemoveAll(filepath.Join(os.TempDir(), subDir))
  557. assert.NoError(t, err)
  558. err = os.Remove(filepath.Join(os.TempDir(), testTxtFile))
  559. assert.NoError(t, err)
  560. }
  561. }
  562. func TestFileAccessErrors(t *testing.T) {
  563. ctx := context.Background()
  564. user := dataprovider.User{
  565. BaseUser: sdk.BaseUser{
  566. HomeDir: filepath.Clean(os.TempDir()),
  567. },
  568. }
  569. user.Permissions = make(map[string][]string)
  570. user.Permissions["/"] = []string{dataprovider.PermAny}
  571. fs := vfs.NewOsFs("connID", user.HomeDir, "")
  572. connection := &Connection{
  573. BaseConnection: common.NewBaseConnection(fs.ConnectionID(), common.ProtocolWebDAV, "", "", user),
  574. }
  575. missingPath := "missing path"
  576. fsMissingPath := filepath.Join(user.HomeDir, missingPath)
  577. err := connection.RemoveAll(ctx, missingPath)
  578. if assert.Error(t, err) {
  579. assert.EqualError(t, err, os.ErrNotExist.Error())
  580. }
  581. _, err = connection.getFile(fs, fsMissingPath, missingPath)
  582. if assert.Error(t, err) {
  583. assert.EqualError(t, err, os.ErrNotExist.Error())
  584. }
  585. _, err = connection.getFile(fs, fsMissingPath, missingPath)
  586. if assert.Error(t, err) {
  587. assert.EqualError(t, err, os.ErrNotExist.Error())
  588. }
  589. p := filepath.Join(user.HomeDir, "adir", missingPath)
  590. _, err = connection.handleUploadToNewFile(fs, p, p, path.Join("adir", missingPath))
  591. if assert.Error(t, err) {
  592. assert.EqualError(t, err, os.ErrNotExist.Error())
  593. }
  594. _, err = connection.handleUploadToExistingFile(fs, p, "_"+p, 0, path.Join("adir", missingPath))
  595. if assert.Error(t, err) {
  596. assert.ErrorIs(t, err, os.ErrNotExist)
  597. }
  598. fs = newMockOsFs(nil, false, fs.ConnectionID(), user.HomeDir, nil)
  599. _, err = connection.handleUploadToExistingFile(fs, p, p, 0, path.Join("adir", missingPath))
  600. if assert.Error(t, err) {
  601. assert.ErrorIs(t, err, os.ErrNotExist)
  602. }
  603. f, err := os.CreateTemp("", "temp")
  604. assert.NoError(t, err)
  605. err = f.Close()
  606. assert.NoError(t, err)
  607. davFile, err := connection.handleUploadToExistingFile(fs, f.Name(), f.Name(), 123, f.Name())
  608. if assert.NoError(t, err) {
  609. transfer := davFile.(*webDavFile)
  610. transfers := connection.GetTransfers()
  611. if assert.Equal(t, 1, len(transfers)) {
  612. assert.Equal(t, transfers[0].ID, transfer.GetID())
  613. assert.Equal(t, int64(123), transfer.InitialSize)
  614. err = transfer.Close()
  615. assert.NoError(t, err)
  616. assert.Equal(t, 0, len(connection.GetTransfers()))
  617. }
  618. // test PROPPATCH date parsing error
  619. pstats, err := transfer.Patch([]webdav.Proppatch{
  620. {
  621. Props: []webdav.Property{
  622. {
  623. XMLName: xml.Name{
  624. Space: "DAV",
  625. Local: "getlastmodified",
  626. },
  627. InnerXML: []byte(`Wid, 04 Nov 2020 13:25:51 GMT`),
  628. },
  629. },
  630. },
  631. })
  632. assert.NoError(t, err)
  633. for _, pstat := range pstats {
  634. assert.Equal(t, http.StatusForbidden, pstat.Status)
  635. }
  636. err = os.Remove(f.Name())
  637. assert.NoError(t, err)
  638. // the file is deleted PROPPATCH should fail
  639. pstats, err = transfer.Patch([]webdav.Proppatch{
  640. {
  641. Props: []webdav.Property{
  642. {
  643. XMLName: xml.Name{
  644. Space: "DAV",
  645. Local: "getlastmodified",
  646. },
  647. InnerXML: []byte(`Wed, 04 Nov 2020 13:25:51 GMT`),
  648. },
  649. },
  650. },
  651. })
  652. assert.NoError(t, err)
  653. for _, pstat := range pstats {
  654. assert.Equal(t, http.StatusForbidden, pstat.Status)
  655. }
  656. }
  657. }
  658. func TestRemoveDirTree(t *testing.T) {
  659. user := dataprovider.User{
  660. BaseUser: sdk.BaseUser{
  661. HomeDir: filepath.Clean(os.TempDir()),
  662. },
  663. }
  664. user.Permissions = make(map[string][]string)
  665. user.Permissions["/"] = []string{dataprovider.PermAny}
  666. fs := vfs.NewOsFs("connID", user.HomeDir, "")
  667. connection := &Connection{
  668. BaseConnection: common.NewBaseConnection(fs.ConnectionID(), common.ProtocolWebDAV, "", "", user),
  669. }
  670. vpath := path.Join("adir", "missing")
  671. p := filepath.Join(user.HomeDir, "adir", "missing")
  672. err := connection.removeDirTree(fs, p, vpath)
  673. if assert.Error(t, err) {
  674. assert.True(t, fs.IsNotExist(err))
  675. }
  676. fs = newMockOsFs(nil, false, "mockID", user.HomeDir, nil)
  677. err = connection.removeDirTree(fs, p, vpath)
  678. if assert.Error(t, err) {
  679. assert.True(t, fs.IsNotExist(err), "unexpected error: %v", err)
  680. }
  681. errFake := errors.New("fake err")
  682. fs = newMockOsFs(errFake, false, "mockID", user.HomeDir, nil)
  683. err = connection.removeDirTree(fs, p, vpath)
  684. if assert.Error(t, err) {
  685. assert.EqualError(t, err, errFake.Error())
  686. }
  687. fs = newMockOsFs(errWalkDir, true, "mockID", user.HomeDir, nil)
  688. err = connection.removeDirTree(fs, p, vpath)
  689. if assert.Error(t, err) {
  690. assert.True(t, fs.IsPermission(err), "unexpected error: %v", err)
  691. }
  692. fs = newMockOsFs(errWalkFile, false, "mockID", user.HomeDir, nil)
  693. err = connection.removeDirTree(fs, p, vpath)
  694. if assert.Error(t, err) {
  695. assert.EqualError(t, err, errWalkFile.Error())
  696. }
  697. connection.User.Permissions["/"] = []string{dataprovider.PermListItems}
  698. fs = newMockOsFs(nil, false, "mockID", user.HomeDir, nil)
  699. err = connection.removeDirTree(fs, p, vpath)
  700. if assert.Error(t, err) {
  701. assert.EqualError(t, err, common.ErrPermissionDenied.Error())
  702. }
  703. }
  704. func TestContentType(t *testing.T) {
  705. user := dataprovider.User{
  706. BaseUser: sdk.BaseUser{
  707. HomeDir: filepath.Clean(os.TempDir()),
  708. },
  709. }
  710. user.Permissions = make(map[string][]string)
  711. user.Permissions["/"] = []string{dataprovider.PermAny}
  712. fs := vfs.NewOsFs("connID", user.HomeDir, "")
  713. connection := &Connection{
  714. BaseConnection: common.NewBaseConnection(fs.ConnectionID(), common.ProtocolWebDAV, "", "", user),
  715. }
  716. testFilePath := filepath.Join(user.HomeDir, testFile)
  717. ctx := context.Background()
  718. baseTransfer := common.NewBaseTransfer(nil, connection.BaseConnection, nil, testFilePath, testFilePath, testFile,
  719. common.TransferDownload, 0, 0, 0, 0, false, fs, dataprovider.TransferQuota{})
  720. fs = newMockOsFs(nil, false, fs.ConnectionID(), user.GetHomeDir(), nil)
  721. err := os.WriteFile(testFilePath, []byte(""), os.ModePerm)
  722. assert.NoError(t, err)
  723. davFile := newWebDavFile(baseTransfer, nil, nil)
  724. davFile.Fs = fs
  725. fi, err := davFile.Stat()
  726. if assert.NoError(t, err) {
  727. ctype, err := fi.(*webDavFileInfo).ContentType(ctx)
  728. assert.NoError(t, err)
  729. assert.Equal(t, "application/custom-mime", ctype)
  730. }
  731. _, err = davFile.Readdir(-1)
  732. assert.Error(t, err)
  733. err = davFile.Close()
  734. assert.NoError(t, err)
  735. davFile = newWebDavFile(baseTransfer, nil, nil)
  736. davFile.Fs = vfs.NewOsFs("id", user.HomeDir, "")
  737. fi, err = davFile.Stat()
  738. if assert.NoError(t, err) {
  739. ctype, err := fi.(*webDavFileInfo).ContentType(ctx)
  740. assert.NoError(t, err)
  741. assert.Equal(t, "text/plain; charset=utf-8", ctype)
  742. }
  743. err = davFile.Close()
  744. assert.NoError(t, err)
  745. fi.(*webDavFileInfo).fsPath = "missing"
  746. _, err = fi.(*webDavFileInfo).ContentType(ctx)
  747. assert.EqualError(t, err, webdav.ErrNotImplemented.Error())
  748. err = os.Remove(testFilePath)
  749. assert.NoError(t, err)
  750. }
  751. func TestTransferReadWriteErrors(t *testing.T) {
  752. user := dataprovider.User{
  753. BaseUser: sdk.BaseUser{
  754. HomeDir: filepath.Clean(os.TempDir()),
  755. },
  756. }
  757. user.Permissions = make(map[string][]string)
  758. user.Permissions["/"] = []string{dataprovider.PermAny}
  759. fs := vfs.NewOsFs("connID", user.HomeDir, "")
  760. connection := &Connection{
  761. BaseConnection: common.NewBaseConnection(fs.ConnectionID(), common.ProtocolWebDAV, "", "", user),
  762. }
  763. testFilePath := filepath.Join(user.HomeDir, testFile)
  764. baseTransfer := common.NewBaseTransfer(nil, connection.BaseConnection, nil, testFilePath, testFilePath, testFile,
  765. common.TransferUpload, 0, 0, 0, 0, false, fs, dataprovider.TransferQuota{})
  766. davFile := newWebDavFile(baseTransfer, nil, nil)
  767. p := make([]byte, 1)
  768. _, err := davFile.Read(p)
  769. assert.EqualError(t, err, common.ErrOpUnsupported.Error())
  770. r, w, err := pipeat.Pipe()
  771. assert.NoError(t, err)
  772. davFile = newWebDavFile(baseTransfer, nil, r)
  773. davFile.Connection.RemoveTransfer(davFile.BaseTransfer)
  774. davFile = newWebDavFile(baseTransfer, vfs.NewPipeWriter(w), nil)
  775. davFile.Connection.RemoveTransfer(davFile.BaseTransfer)
  776. err = r.Close()
  777. assert.NoError(t, err)
  778. err = w.Close()
  779. assert.NoError(t, err)
  780. baseTransfer = common.NewBaseTransfer(nil, connection.BaseConnection, nil, testFilePath, testFilePath, testFile,
  781. common.TransferDownload, 0, 0, 0, 0, false, fs, dataprovider.TransferQuota{})
  782. davFile = newWebDavFile(baseTransfer, nil, nil)
  783. _, err = davFile.Read(p)
  784. assert.True(t, fs.IsNotExist(err))
  785. _, err = davFile.Stat()
  786. assert.True(t, fs.IsNotExist(err))
  787. baseTransfer = common.NewBaseTransfer(nil, connection.BaseConnection, nil, testFilePath, testFilePath, testFile,
  788. common.TransferDownload, 0, 0, 0, 0, false, fs, dataprovider.TransferQuota{})
  789. err = os.WriteFile(testFilePath, []byte(""), os.ModePerm)
  790. assert.NoError(t, err)
  791. f, err := os.Open(testFilePath)
  792. if assert.NoError(t, err) {
  793. err = f.Close()
  794. assert.NoError(t, err)
  795. }
  796. davFile = newWebDavFile(baseTransfer, nil, nil)
  797. davFile.reader = f
  798. err = davFile.Close()
  799. assert.EqualError(t, err, common.ErrGenericFailure.Error())
  800. err = davFile.Close()
  801. assert.EqualError(t, err, common.ErrTransferClosed.Error())
  802. _, err = davFile.Read(p)
  803. assert.Error(t, err)
  804. info, err := davFile.Stat()
  805. if assert.NoError(t, err) {
  806. assert.Equal(t, int64(0), info.Size())
  807. }
  808. r, w, err = pipeat.Pipe()
  809. assert.NoError(t, err)
  810. mockFs := newMockOsFs(nil, false, fs.ConnectionID(), user.HomeDir, r)
  811. baseTransfer = common.NewBaseTransfer(nil, connection.BaseConnection, nil, testFilePath, testFilePath, testFile,
  812. common.TransferDownload, 0, 0, 0, 0, false, mockFs, dataprovider.TransferQuota{})
  813. davFile = newWebDavFile(baseTransfer, nil, nil)
  814. writeContent := []byte("content\r\n")
  815. go func() {
  816. n, err := w.Write(writeContent)
  817. assert.NoError(t, err)
  818. assert.Equal(t, len(writeContent), n)
  819. err = w.Close()
  820. assert.NoError(t, err)
  821. }()
  822. p = make([]byte, 64)
  823. n, err := davFile.Read(p)
  824. assert.EqualError(t, err, io.EOF.Error())
  825. assert.Equal(t, len(writeContent), n)
  826. err = davFile.Close()
  827. assert.NoError(t, err)
  828. baseTransfer = common.NewBaseTransfer(nil, connection.BaseConnection, nil, testFilePath, testFilePath, testFile,
  829. common.TransferDownload, 0, 0, 0, 0, false, fs, dataprovider.TransferQuota{})
  830. davFile = newWebDavFile(baseTransfer, nil, nil)
  831. davFile.writer = f
  832. err = davFile.Close()
  833. assert.EqualError(t, err, common.ErrGenericFailure.Error())
  834. err = os.Remove(testFilePath)
  835. assert.NoError(t, err)
  836. }
  837. func TestTransferSeek(t *testing.T) {
  838. user := dataprovider.User{
  839. BaseUser: sdk.BaseUser{
  840. HomeDir: filepath.Clean(os.TempDir()),
  841. },
  842. }
  843. user.Permissions = make(map[string][]string)
  844. user.Permissions["/"] = []string{dataprovider.PermAny}
  845. fs := vfs.NewOsFs("connID", user.HomeDir, "")
  846. connection := &Connection{
  847. BaseConnection: common.NewBaseConnection(fs.ConnectionID(), common.ProtocolWebDAV, "", "", user),
  848. }
  849. testFilePath := filepath.Join(user.HomeDir, testFile)
  850. testFileContents := []byte("content")
  851. baseTransfer := common.NewBaseTransfer(nil, connection.BaseConnection, nil, testFilePath, testFilePath, testFile,
  852. common.TransferUpload, 0, 0, 0, 0, false, fs, dataprovider.TransferQuota{AllowedTotalSize: 100})
  853. davFile := newWebDavFile(baseTransfer, nil, nil)
  854. _, err := davFile.Seek(0, io.SeekStart)
  855. assert.EqualError(t, err, common.ErrOpUnsupported.Error())
  856. err = davFile.Close()
  857. assert.NoError(t, err)
  858. baseTransfer = common.NewBaseTransfer(nil, connection.BaseConnection, nil, testFilePath, testFilePath, testFile,
  859. common.TransferDownload, 0, 0, 0, 0, false, fs, dataprovider.TransferQuota{AllowedTotalSize: 100})
  860. davFile = newWebDavFile(baseTransfer, nil, nil)
  861. _, err = davFile.Seek(0, io.SeekCurrent)
  862. assert.True(t, fs.IsNotExist(err))
  863. davFile.Connection.RemoveTransfer(davFile.BaseTransfer)
  864. err = os.WriteFile(testFilePath, testFileContents, os.ModePerm)
  865. assert.NoError(t, err)
  866. f, err := os.Open(testFilePath)
  867. if assert.NoError(t, err) {
  868. err = f.Close()
  869. assert.NoError(t, err)
  870. }
  871. baseTransfer = common.NewBaseTransfer(f, connection.BaseConnection, nil, testFilePath, testFilePath, testFile,
  872. common.TransferDownload, 0, 0, 0, 0, false, fs, dataprovider.TransferQuota{AllowedTotalSize: 100})
  873. davFile = newWebDavFile(baseTransfer, nil, nil)
  874. _, err = davFile.Seek(0, io.SeekStart)
  875. assert.Error(t, err)
  876. davFile.Connection.RemoveTransfer(davFile.BaseTransfer)
  877. baseTransfer = common.NewBaseTransfer(nil, connection.BaseConnection, nil, testFilePath, testFilePath, testFile,
  878. common.TransferDownload, 0, 0, 0, 0, false, fs, dataprovider.TransferQuota{AllowedTotalSize: 100})
  879. davFile = newWebDavFile(baseTransfer, nil, nil)
  880. res, err := davFile.Seek(0, io.SeekStart)
  881. assert.NoError(t, err)
  882. assert.Equal(t, int64(0), res)
  883. davFile.Connection.RemoveTransfer(davFile.BaseTransfer)
  884. davFile = newWebDavFile(baseTransfer, nil, nil)
  885. res, err = davFile.Seek(0, io.SeekEnd)
  886. assert.NoError(t, err)
  887. assert.Equal(t, int64(len(testFileContents)), res)
  888. err = davFile.updateStatInfo()
  889. assert.Nil(t, err)
  890. baseTransfer = common.NewBaseTransfer(nil, connection.BaseConnection, nil, testFilePath+"1", testFilePath+"1", testFile,
  891. common.TransferDownload, 0, 0, 0, 0, false, fs, dataprovider.TransferQuota{AllowedTotalSize: 100})
  892. davFile = newWebDavFile(baseTransfer, nil, nil)
  893. _, err = davFile.Seek(0, io.SeekEnd)
  894. assert.True(t, fs.IsNotExist(err))
  895. davFile.Connection.RemoveTransfer(davFile.BaseTransfer)
  896. baseTransfer = common.NewBaseTransfer(nil, connection.BaseConnection, nil, testFilePath, testFilePath, testFile,
  897. common.TransferDownload, 0, 0, 0, 0, false, fs, dataprovider.TransferQuota{AllowedTotalSize: 100})
  898. davFile = newWebDavFile(baseTransfer, nil, nil)
  899. davFile.reader = f
  900. davFile.Fs = newMockOsFs(nil, true, fs.ConnectionID(), user.GetHomeDir(), nil)
  901. res, err = davFile.Seek(2, io.SeekStart)
  902. assert.NoError(t, err)
  903. assert.Equal(t, int64(2), res)
  904. davFile = newWebDavFile(baseTransfer, nil, nil)
  905. davFile.Fs = newMockOsFs(nil, true, fs.ConnectionID(), user.GetHomeDir(), nil)
  906. res, err = davFile.Seek(2, io.SeekEnd)
  907. assert.NoError(t, err)
  908. assert.Equal(t, int64(5), res)
  909. baseTransfer = common.NewBaseTransfer(nil, connection.BaseConnection, nil, testFilePath+"1", testFilePath+"1", testFile,
  910. common.TransferDownload, 0, 0, 0, 0, false, fs, dataprovider.TransferQuota{AllowedTotalSize: 100})
  911. davFile = newWebDavFile(baseTransfer, nil, nil)
  912. davFile.Fs = newMockOsFs(nil, true, fs.ConnectionID(), user.GetHomeDir(), nil)
  913. res, err = davFile.Seek(2, io.SeekEnd)
  914. assert.True(t, fs.IsNotExist(err))
  915. assert.Equal(t, int64(0), res)
  916. assert.Len(t, common.Connections.GetStats(), 0)
  917. err = os.Remove(testFilePath)
  918. assert.NoError(t, err)
  919. }
  920. func TestBasicUsersCache(t *testing.T) {
  921. username := "webdav_internal_test"
  922. password := "pwd"
  923. u := dataprovider.User{
  924. BaseUser: sdk.BaseUser{
  925. Username: username,
  926. Password: password,
  927. HomeDir: filepath.Join(os.TempDir(), username),
  928. Status: 1,
  929. ExpirationDate: 0,
  930. },
  931. }
  932. u.Permissions = make(map[string][]string)
  933. u.Permissions["/"] = []string{dataprovider.PermAny}
  934. err := dataprovider.AddUser(&u, "", "")
  935. assert.NoError(t, err)
  936. user, err := dataprovider.UserExists(u.Username)
  937. assert.NoError(t, err)
  938. c := &Configuration{
  939. Bindings: []Binding{
  940. {
  941. Port: 9000,
  942. },
  943. },
  944. Cache: Cache{
  945. Users: UsersCacheConfig{
  946. MaxSize: 50,
  947. ExpirationTime: 1,
  948. },
  949. },
  950. }
  951. dataprovider.InitializeWebDAVUserCache(c.Cache.Users.MaxSize)
  952. server := webDavServer{
  953. config: c,
  954. binding: c.Bindings[0],
  955. }
  956. req, err := http.NewRequest(http.MethodGet, fmt.Sprintf("/%v", user.Username), nil)
  957. assert.NoError(t, err)
  958. ipAddr := "127.0.0.1"
  959. _, _, _, _, err = server.authenticate(req, ipAddr) //nolint:dogsled
  960. assert.Error(t, err)
  961. now := time.Now()
  962. req.SetBasicAuth(username, password)
  963. _, isCached, _, loginMethod, err := server.authenticate(req, ipAddr)
  964. assert.NoError(t, err)
  965. assert.False(t, isCached)
  966. assert.Equal(t, dataprovider.LoginMethodPassword, loginMethod)
  967. // now the user should be cached
  968. cachedUser, ok := dataprovider.GetCachedWebDAVUser(username)
  969. if assert.True(t, ok) {
  970. assert.False(t, cachedUser.IsExpired())
  971. assert.True(t, cachedUser.Expiration.After(now.Add(time.Duration(c.Cache.Users.ExpirationTime)*time.Minute)))
  972. // authenticate must return the cached user now
  973. authUser, isCached, _, _, err := server.authenticate(req, ipAddr)
  974. assert.NoError(t, err)
  975. assert.True(t, isCached)
  976. assert.Equal(t, cachedUser.User, authUser)
  977. }
  978. // a wrong password must fail
  979. req.SetBasicAuth(username, "wrong")
  980. _, _, _, _, err = server.authenticate(req, ipAddr) //nolint:dogsled
  981. assert.EqualError(t, err, dataprovider.ErrInvalidCredentials.Error())
  982. req.SetBasicAuth(username, password)
  983. // force cached user expiration
  984. cachedUser.Expiration = now
  985. dataprovider.CacheWebDAVUser(cachedUser)
  986. cachedUser, ok = dataprovider.GetCachedWebDAVUser(username)
  987. if assert.True(t, ok) {
  988. assert.True(t, cachedUser.IsExpired())
  989. }
  990. // now authenticate should get the user from the data provider and update the cache
  991. _, isCached, _, loginMethod, err = server.authenticate(req, ipAddr)
  992. assert.NoError(t, err)
  993. assert.False(t, isCached)
  994. assert.Equal(t, dataprovider.LoginMethodPassword, loginMethod)
  995. cachedUser, ok = dataprovider.GetCachedWebDAVUser(username)
  996. if assert.True(t, ok) {
  997. assert.False(t, cachedUser.IsExpired())
  998. }
  999. // cache is not invalidated after a user modification if the fs does not change
  1000. err = dataprovider.UpdateUser(&user, "", "")
  1001. assert.NoError(t, err)
  1002. _, ok = dataprovider.GetCachedWebDAVUser(username)
  1003. assert.True(t, ok)
  1004. folderName := "testFolder"
  1005. user.VirtualFolders = append(user.VirtualFolders, vfs.VirtualFolder{
  1006. BaseVirtualFolder: vfs.BaseVirtualFolder{
  1007. Name: folderName,
  1008. MappedPath: filepath.Join(os.TempDir(), "mapped"),
  1009. },
  1010. VirtualPath: "/vdir",
  1011. })
  1012. err = dataprovider.UpdateUser(&user, "", "")
  1013. assert.NoError(t, err)
  1014. _, ok = dataprovider.GetCachedWebDAVUser(username)
  1015. assert.False(t, ok)
  1016. _, isCached, _, loginMethod, err = server.authenticate(req, ipAddr)
  1017. assert.NoError(t, err)
  1018. assert.False(t, isCached)
  1019. assert.Equal(t, dataprovider.LoginMethodPassword, loginMethod)
  1020. _, ok = dataprovider.GetCachedWebDAVUser(username)
  1021. assert.True(t, ok)
  1022. // cache is invalidated after user deletion
  1023. err = dataprovider.DeleteUser(user.Username, "", "")
  1024. assert.NoError(t, err)
  1025. _, ok = dataprovider.GetCachedWebDAVUser(username)
  1026. assert.False(t, ok)
  1027. err = dataprovider.DeleteFolder(folderName, "", "")
  1028. assert.NoError(t, err)
  1029. err = os.RemoveAll(u.GetHomeDir())
  1030. assert.NoError(t, err)
  1031. }
  1032. func TestCachedUserWithFolders(t *testing.T) {
  1033. username := "webdav_internal_folder_test"
  1034. password := "dav_pwd"
  1035. folderName := "test_folder"
  1036. u := dataprovider.User{
  1037. BaseUser: sdk.BaseUser{
  1038. Username: username,
  1039. Password: password,
  1040. HomeDir: filepath.Join(os.TempDir(), username),
  1041. Status: 1,
  1042. ExpirationDate: 0,
  1043. },
  1044. }
  1045. u.Permissions = make(map[string][]string)
  1046. u.Permissions["/"] = []string{dataprovider.PermAny}
  1047. u.VirtualFolders = append(u.VirtualFolders, vfs.VirtualFolder{
  1048. BaseVirtualFolder: vfs.BaseVirtualFolder{
  1049. Name: folderName,
  1050. MappedPath: filepath.Join(os.TempDir(), folderName),
  1051. },
  1052. VirtualPath: "/vpath",
  1053. })
  1054. err := dataprovider.AddUser(&u, "", "")
  1055. assert.NoError(t, err)
  1056. user, err := dataprovider.UserExists(u.Username)
  1057. assert.NoError(t, err)
  1058. c := &Configuration{
  1059. Bindings: []Binding{
  1060. {
  1061. Port: 9000,
  1062. },
  1063. },
  1064. Cache: Cache{
  1065. Users: UsersCacheConfig{
  1066. MaxSize: 50,
  1067. ExpirationTime: 1,
  1068. },
  1069. },
  1070. }
  1071. dataprovider.InitializeWebDAVUserCache(c.Cache.Users.MaxSize)
  1072. server := webDavServer{
  1073. config: c,
  1074. binding: c.Bindings[0],
  1075. }
  1076. req, err := http.NewRequest(http.MethodGet, fmt.Sprintf("/%v", user.Username), nil)
  1077. assert.NoError(t, err)
  1078. ipAddr := "127.0.0.1"
  1079. _, _, _, _, err = server.authenticate(req, ipAddr) //nolint:dogsled
  1080. assert.Error(t, err)
  1081. now := time.Now()
  1082. req.SetBasicAuth(username, password)
  1083. _, isCached, _, loginMethod, err := server.authenticate(req, ipAddr)
  1084. assert.NoError(t, err)
  1085. assert.False(t, isCached)
  1086. assert.Equal(t, dataprovider.LoginMethodPassword, loginMethod)
  1087. // now the user should be cached
  1088. cachedUser, ok := dataprovider.GetCachedWebDAVUser(username)
  1089. if assert.True(t, ok) {
  1090. assert.False(t, cachedUser.IsExpired())
  1091. assert.True(t, cachedUser.Expiration.After(now.Add(time.Duration(c.Cache.Users.ExpirationTime)*time.Minute)))
  1092. // authenticate must return the cached user now
  1093. authUser, isCached, _, _, err := server.authenticate(req, ipAddr)
  1094. assert.NoError(t, err)
  1095. assert.True(t, isCached)
  1096. assert.Equal(t, cachedUser.User, authUser)
  1097. }
  1098. folder, err := dataprovider.GetFolderByName(folderName)
  1099. assert.NoError(t, err)
  1100. // updating a used folder should invalidate the cache only if the fs changed
  1101. err = dataprovider.UpdateFolder(&folder, folder.Users, folder.Groups, "", "")
  1102. assert.NoError(t, err)
  1103. _, isCached, _, loginMethod, err = server.authenticate(req, ipAddr)
  1104. assert.NoError(t, err)
  1105. assert.True(t, isCached)
  1106. assert.Equal(t, dataprovider.LoginMethodPassword, loginMethod)
  1107. cachedUser, ok = dataprovider.GetCachedWebDAVUser(username)
  1108. if assert.True(t, ok) {
  1109. assert.False(t, cachedUser.IsExpired())
  1110. }
  1111. // changing the folder path should invalidate the cache
  1112. folder.MappedPath = filepath.Join(os.TempDir(), "anotherpath")
  1113. err = dataprovider.UpdateFolder(&folder, folder.Users, folder.Groups, "", "")
  1114. assert.NoError(t, err)
  1115. _, isCached, _, loginMethod, err = server.authenticate(req, ipAddr)
  1116. assert.NoError(t, err)
  1117. assert.False(t, isCached)
  1118. assert.Equal(t, dataprovider.LoginMethodPassword, loginMethod)
  1119. cachedUser, ok = dataprovider.GetCachedWebDAVUser(username)
  1120. if assert.True(t, ok) {
  1121. assert.False(t, cachedUser.IsExpired())
  1122. }
  1123. err = dataprovider.DeleteFolder(folderName, "", "")
  1124. assert.NoError(t, err)
  1125. // removing a used folder should invalidate the cache
  1126. _, isCached, _, loginMethod, err = server.authenticate(req, ipAddr)
  1127. assert.NoError(t, err)
  1128. assert.False(t, isCached)
  1129. assert.Equal(t, dataprovider.LoginMethodPassword, loginMethod)
  1130. cachedUser, ok = dataprovider.GetCachedWebDAVUser(username)
  1131. if assert.True(t, ok) {
  1132. assert.False(t, cachedUser.IsExpired())
  1133. }
  1134. err = dataprovider.DeleteUser(user.Username, "", "")
  1135. assert.NoError(t, err)
  1136. _, ok = dataprovider.GetCachedWebDAVUser(username)
  1137. assert.False(t, ok)
  1138. err = os.RemoveAll(u.GetHomeDir())
  1139. assert.NoError(t, err)
  1140. err = os.RemoveAll(folder.MappedPath)
  1141. assert.NoError(t, err)
  1142. }
  1143. func TestUsersCacheSizeAndExpiration(t *testing.T) {
  1144. username := "webdav_internal_test"
  1145. password := "pwd"
  1146. u := dataprovider.User{
  1147. BaseUser: sdk.BaseUser{
  1148. HomeDir: filepath.Join(os.TempDir(), username),
  1149. Status: 1,
  1150. ExpirationDate: 0,
  1151. },
  1152. }
  1153. u.Username = username + "1"
  1154. u.Password = password + "1"
  1155. u.Permissions = make(map[string][]string)
  1156. u.Permissions["/"] = []string{dataprovider.PermAny}
  1157. err := dataprovider.AddUser(&u, "", "")
  1158. assert.NoError(t, err)
  1159. user1, err := dataprovider.UserExists(u.Username)
  1160. assert.NoError(t, err)
  1161. u.Username = username + "2"
  1162. u.Password = password + "2"
  1163. err = dataprovider.AddUser(&u, "", "")
  1164. assert.NoError(t, err)
  1165. user2, err := dataprovider.UserExists(u.Username)
  1166. assert.NoError(t, err)
  1167. u.Username = username + "3"
  1168. u.Password = password + "3"
  1169. err = dataprovider.AddUser(&u, "", "")
  1170. assert.NoError(t, err)
  1171. user3, err := dataprovider.UserExists(u.Username)
  1172. assert.NoError(t, err)
  1173. u.Username = username + "4"
  1174. u.Password = password + "4"
  1175. err = dataprovider.AddUser(&u, "", "")
  1176. assert.NoError(t, err)
  1177. user4, err := dataprovider.UserExists(u.Username)
  1178. assert.NoError(t, err)
  1179. c := &Configuration{
  1180. Bindings: []Binding{
  1181. {
  1182. Port: 9000,
  1183. },
  1184. },
  1185. Cache: Cache{
  1186. Users: UsersCacheConfig{
  1187. MaxSize: 3,
  1188. ExpirationTime: 1,
  1189. },
  1190. },
  1191. }
  1192. dataprovider.InitializeWebDAVUserCache(c.Cache.Users.MaxSize)
  1193. server := webDavServer{
  1194. config: c,
  1195. binding: c.Bindings[0],
  1196. }
  1197. ipAddr := "127.0.1.1"
  1198. req, err := http.NewRequest(http.MethodGet, fmt.Sprintf("/%v", user1.Username), nil)
  1199. assert.NoError(t, err)
  1200. req.SetBasicAuth(user1.Username, password+"1")
  1201. _, isCached, _, loginMehod, err := server.authenticate(req, ipAddr)
  1202. assert.NoError(t, err)
  1203. assert.False(t, isCached)
  1204. assert.Equal(t, dataprovider.LoginMethodPassword, loginMehod)
  1205. req, err = http.NewRequest(http.MethodGet, fmt.Sprintf("/%v", user2.Username), nil)
  1206. assert.NoError(t, err)
  1207. req.SetBasicAuth(user2.Username, password+"2")
  1208. _, isCached, _, loginMehod, err = server.authenticate(req, ipAddr)
  1209. assert.NoError(t, err)
  1210. assert.False(t, isCached)
  1211. assert.Equal(t, dataprovider.LoginMethodPassword, loginMehod)
  1212. req, err = http.NewRequest(http.MethodGet, fmt.Sprintf("/%v", user3.Username), nil)
  1213. assert.NoError(t, err)
  1214. req.SetBasicAuth(user3.Username, password+"3")
  1215. _, isCached, _, loginMehod, err = server.authenticate(req, ipAddr)
  1216. assert.NoError(t, err)
  1217. assert.False(t, isCached)
  1218. assert.Equal(t, dataprovider.LoginMethodPassword, loginMehod)
  1219. // the first 3 users are now cached
  1220. _, ok := dataprovider.GetCachedWebDAVUser(user1.Username)
  1221. assert.True(t, ok)
  1222. _, ok = dataprovider.GetCachedWebDAVUser(user2.Username)
  1223. assert.True(t, ok)
  1224. _, ok = dataprovider.GetCachedWebDAVUser(user3.Username)
  1225. assert.True(t, ok)
  1226. req, err = http.NewRequest(http.MethodGet, fmt.Sprintf("/%v", user4.Username), nil)
  1227. assert.NoError(t, err)
  1228. req.SetBasicAuth(user4.Username, password+"4")
  1229. _, isCached, _, loginMehod, err = server.authenticate(req, ipAddr)
  1230. assert.NoError(t, err)
  1231. assert.False(t, isCached)
  1232. assert.Equal(t, dataprovider.LoginMethodPassword, loginMehod)
  1233. // user1, the first cached, should be removed now
  1234. _, ok = dataprovider.GetCachedWebDAVUser(user1.Username)
  1235. assert.False(t, ok)
  1236. _, ok = dataprovider.GetCachedWebDAVUser(user2.Username)
  1237. assert.True(t, ok)
  1238. _, ok = dataprovider.GetCachedWebDAVUser(user3.Username)
  1239. assert.True(t, ok)
  1240. _, ok = dataprovider.GetCachedWebDAVUser(user4.Username)
  1241. assert.True(t, ok)
  1242. // a sleep ensures that expiration times are different
  1243. time.Sleep(20 * time.Millisecond)
  1244. // user1 logins, user2 should be removed
  1245. req, err = http.NewRequest(http.MethodGet, fmt.Sprintf("/%v", user1.Username), nil)
  1246. assert.NoError(t, err)
  1247. req.SetBasicAuth(user1.Username, password+"1")
  1248. _, isCached, _, loginMehod, err = server.authenticate(req, ipAddr)
  1249. assert.NoError(t, err)
  1250. assert.False(t, isCached)
  1251. assert.Equal(t, dataprovider.LoginMethodPassword, loginMehod)
  1252. _, ok = dataprovider.GetCachedWebDAVUser(user2.Username)
  1253. assert.False(t, ok)
  1254. _, ok = dataprovider.GetCachedWebDAVUser(user1.Username)
  1255. assert.True(t, ok)
  1256. _, ok = dataprovider.GetCachedWebDAVUser(user3.Username)
  1257. assert.True(t, ok)
  1258. _, ok = dataprovider.GetCachedWebDAVUser(user4.Username)
  1259. assert.True(t, ok)
  1260. // a sleep ensures that expiration times are different
  1261. time.Sleep(20 * time.Millisecond)
  1262. // user2 logins, user3 should be removed
  1263. req, err = http.NewRequest(http.MethodGet, fmt.Sprintf("/%v", user2.Username), nil)
  1264. assert.NoError(t, err)
  1265. req.SetBasicAuth(user2.Username, password+"2")
  1266. _, isCached, _, loginMehod, err = server.authenticate(req, ipAddr)
  1267. assert.NoError(t, err)
  1268. assert.False(t, isCached)
  1269. assert.Equal(t, dataprovider.LoginMethodPassword, loginMehod)
  1270. _, ok = dataprovider.GetCachedWebDAVUser(user3.Username)
  1271. assert.False(t, ok)
  1272. _, ok = dataprovider.GetCachedWebDAVUser(user1.Username)
  1273. assert.True(t, ok)
  1274. _, ok = dataprovider.GetCachedWebDAVUser(user2.Username)
  1275. assert.True(t, ok)
  1276. _, ok = dataprovider.GetCachedWebDAVUser(user4.Username)
  1277. assert.True(t, ok)
  1278. // a sleep ensures that expiration times are different
  1279. time.Sleep(20 * time.Millisecond)
  1280. // user3 logins, user4 should be removed
  1281. req, err = http.NewRequest(http.MethodGet, fmt.Sprintf("/%v", user3.Username), nil)
  1282. assert.NoError(t, err)
  1283. req.SetBasicAuth(user3.Username, password+"3")
  1284. _, isCached, _, loginMehod, err = server.authenticate(req, ipAddr)
  1285. assert.NoError(t, err)
  1286. assert.False(t, isCached)
  1287. assert.Equal(t, dataprovider.LoginMethodPassword, loginMehod)
  1288. _, ok = dataprovider.GetCachedWebDAVUser(user4.Username)
  1289. assert.False(t, ok)
  1290. _, ok = dataprovider.GetCachedWebDAVUser(user1.Username)
  1291. assert.True(t, ok)
  1292. _, ok = dataprovider.GetCachedWebDAVUser(user2.Username)
  1293. assert.True(t, ok)
  1294. _, ok = dataprovider.GetCachedWebDAVUser(user3.Username)
  1295. assert.True(t, ok)
  1296. // now remove user1 after an update
  1297. user1.HomeDir += "_mod"
  1298. err = dataprovider.UpdateUser(&user1, "", "")
  1299. assert.NoError(t, err)
  1300. _, ok = dataprovider.GetCachedWebDAVUser(user1.Username)
  1301. assert.False(t, ok)
  1302. req, err = http.NewRequest(http.MethodGet, fmt.Sprintf("/%v", user4.Username), nil)
  1303. assert.NoError(t, err)
  1304. req.SetBasicAuth(user4.Username, password+"4")
  1305. _, isCached, _, loginMehod, err = server.authenticate(req, ipAddr)
  1306. assert.NoError(t, err)
  1307. assert.False(t, isCached)
  1308. assert.Equal(t, dataprovider.LoginMethodPassword, loginMehod)
  1309. // a sleep ensures that expiration times are different
  1310. time.Sleep(20 * time.Millisecond)
  1311. req, err = http.NewRequest(http.MethodGet, fmt.Sprintf("/%v", user1.Username), nil)
  1312. assert.NoError(t, err)
  1313. req.SetBasicAuth(user1.Username, password+"1")
  1314. _, isCached, _, loginMehod, err = server.authenticate(req, ipAddr)
  1315. assert.NoError(t, err)
  1316. assert.False(t, isCached)
  1317. assert.Equal(t, dataprovider.LoginMethodPassword, loginMehod)
  1318. _, ok = dataprovider.GetCachedWebDAVUser(user2.Username)
  1319. assert.False(t, ok)
  1320. _, ok = dataprovider.GetCachedWebDAVUser(user1.Username)
  1321. assert.True(t, ok)
  1322. _, ok = dataprovider.GetCachedWebDAVUser(user3.Username)
  1323. assert.True(t, ok)
  1324. _, ok = dataprovider.GetCachedWebDAVUser(user4.Username)
  1325. assert.True(t, ok)
  1326. err = dataprovider.DeleteUser(user1.Username, "", "")
  1327. assert.NoError(t, err)
  1328. err = dataprovider.DeleteUser(user2.Username, "", "")
  1329. assert.NoError(t, err)
  1330. err = dataprovider.DeleteUser(user3.Username, "", "")
  1331. assert.NoError(t, err)
  1332. err = dataprovider.DeleteUser(user4.Username, "", "")
  1333. assert.NoError(t, err)
  1334. err = os.RemoveAll(u.GetHomeDir())
  1335. assert.NoError(t, err)
  1336. }
  1337. func TestUserCacheIsolation(t *testing.T) {
  1338. dataprovider.InitializeWebDAVUserCache(10)
  1339. username := "webdav_internal_cache_test"
  1340. password := "dav_pwd"
  1341. u := dataprovider.User{
  1342. BaseUser: sdk.BaseUser{
  1343. Username: username,
  1344. Password: password,
  1345. HomeDir: filepath.Join(os.TempDir(), username),
  1346. Status: 1,
  1347. ExpirationDate: 0,
  1348. },
  1349. }
  1350. u.Permissions = make(map[string][]string)
  1351. u.Permissions["/"] = []string{dataprovider.PermAny}
  1352. err := dataprovider.AddUser(&u, "", "")
  1353. assert.NoError(t, err)
  1354. user, err := dataprovider.UserExists(u.Username)
  1355. assert.NoError(t, err)
  1356. cachedUser := &dataprovider.CachedUser{
  1357. User: user,
  1358. Expiration: time.Now().Add(24 * time.Hour),
  1359. Password: password,
  1360. LockSystem: webdav.NewMemLS(),
  1361. }
  1362. cachedUser.User.FsConfig.S3Config.AccessSecret = kms.NewPlainSecret("test secret")
  1363. err = cachedUser.User.FsConfig.S3Config.AccessSecret.Encrypt()
  1364. assert.NoError(t, err)
  1365. dataprovider.CacheWebDAVUser(cachedUser)
  1366. cachedUser, ok := dataprovider.GetCachedWebDAVUser(username)
  1367. if assert.True(t, ok) {
  1368. _, err = cachedUser.User.GetFilesystem("")
  1369. assert.NoError(t, err)
  1370. // the filesystem is now cached
  1371. }
  1372. cachedUser, ok = dataprovider.GetCachedWebDAVUser(username)
  1373. if assert.True(t, ok) {
  1374. assert.True(t, cachedUser.User.FsConfig.S3Config.AccessSecret.IsEncrypted())
  1375. err = cachedUser.User.FsConfig.S3Config.AccessSecret.Decrypt()
  1376. assert.NoError(t, err)
  1377. cachedUser.User.FsConfig.Provider = sdk.S3FilesystemProvider
  1378. _, err = cachedUser.User.GetFilesystem("")
  1379. assert.Error(t, err, "we don't have to get the previously cached filesystem!")
  1380. }
  1381. cachedUser, ok = dataprovider.GetCachedWebDAVUser(username)
  1382. if assert.True(t, ok) {
  1383. assert.Equal(t, sdk.LocalFilesystemProvider, cachedUser.User.FsConfig.Provider)
  1384. assert.False(t, cachedUser.User.FsConfig.S3Config.AccessSecret.IsEncrypted())
  1385. }
  1386. err = dataprovider.DeleteUser(username, "", "")
  1387. assert.NoError(t, err)
  1388. _, ok = dataprovider.GetCachedWebDAVUser(username)
  1389. assert.False(t, ok)
  1390. }
  1391. func TestRecoverer(t *testing.T) {
  1392. c := &Configuration{
  1393. Bindings: []Binding{
  1394. {
  1395. Port: 9000,
  1396. },
  1397. },
  1398. }
  1399. server := webDavServer{
  1400. config: c,
  1401. binding: c.Bindings[0],
  1402. }
  1403. rr := httptest.NewRecorder()
  1404. server.ServeHTTP(rr, nil)
  1405. assert.Equal(t, http.StatusInternalServerError, rr.Code)
  1406. }
  1407. func TestMimeCache(t *testing.T) {
  1408. cache := mimeCache{
  1409. maxSize: 0,
  1410. mimeTypes: make(map[string]string),
  1411. }
  1412. cache.addMimeToCache(".zip", "application/zip")
  1413. mtype := cache.getMimeFromCache(".zip")
  1414. assert.Equal(t, "", mtype)
  1415. cache.maxSize = 1
  1416. cache.addMimeToCache(".zip", "application/zip")
  1417. mtype = cache.getMimeFromCache(".zip")
  1418. assert.Equal(t, "application/zip", mtype)
  1419. cache.addMimeToCache(".jpg", "image/jpeg")
  1420. mtype = cache.getMimeFromCache(".jpg")
  1421. assert.Equal(t, "", mtype)
  1422. }
  1423. func TestVerifyTLSConnection(t *testing.T) {
  1424. oldCertMgr := certMgr
  1425. caCrlPath := filepath.Join(os.TempDir(), "testcrl.crt")
  1426. certPath := filepath.Join(os.TempDir(), "test.crt")
  1427. keyPath := filepath.Join(os.TempDir(), "test.key")
  1428. err := os.WriteFile(caCrlPath, []byte(caCRL), os.ModePerm)
  1429. assert.NoError(t, err)
  1430. err = os.WriteFile(certPath, []byte(webDavCert), os.ModePerm)
  1431. assert.NoError(t, err)
  1432. err = os.WriteFile(keyPath, []byte(webDavKey), os.ModePerm)
  1433. assert.NoError(t, err)
  1434. keyPairs := []common.TLSKeyPair{
  1435. {
  1436. Cert: certPath,
  1437. Key: keyPath,
  1438. ID: common.DefaultTLSKeyPaidID,
  1439. },
  1440. }
  1441. certMgr, err = common.NewCertManager(keyPairs, "", "webdav_test")
  1442. assert.NoError(t, err)
  1443. certMgr.SetCARevocationLists([]string{caCrlPath})
  1444. err = certMgr.LoadCRLs()
  1445. assert.NoError(t, err)
  1446. crt, err := tls.X509KeyPair([]byte(client1Crt), []byte(client1Key))
  1447. assert.NoError(t, err)
  1448. x509crt, err := x509.ParseCertificate(crt.Certificate[0])
  1449. assert.NoError(t, err)
  1450. server := webDavServer{}
  1451. state := tls.ConnectionState{
  1452. PeerCertificates: []*x509.Certificate{x509crt},
  1453. }
  1454. err = server.verifyTLSConnection(state)
  1455. assert.Error(t, err) // no verified certification chain
  1456. crt, err = tls.X509KeyPair([]byte(caCRT), []byte(caKey))
  1457. assert.NoError(t, err)
  1458. x509CAcrt, err := x509.ParseCertificate(crt.Certificate[0])
  1459. assert.NoError(t, err)
  1460. state.VerifiedChains = append(state.VerifiedChains, []*x509.Certificate{x509crt, x509CAcrt})
  1461. err = server.verifyTLSConnection(state)
  1462. assert.NoError(t, err)
  1463. crt, err = tls.X509KeyPair([]byte(client2Crt), []byte(client2Key))
  1464. assert.NoError(t, err)
  1465. x509crtRevoked, err := x509.ParseCertificate(crt.Certificate[0])
  1466. assert.NoError(t, err)
  1467. state.VerifiedChains = append(state.VerifiedChains, []*x509.Certificate{x509crtRevoked, x509CAcrt})
  1468. state.PeerCertificates = []*x509.Certificate{x509crtRevoked}
  1469. err = server.verifyTLSConnection(state)
  1470. assert.EqualError(t, err, common.ErrCrtRevoked.Error())
  1471. err = os.Remove(caCrlPath)
  1472. assert.NoError(t, err)
  1473. err = os.Remove(certPath)
  1474. assert.NoError(t, err)
  1475. err = os.Remove(keyPath)
  1476. assert.NoError(t, err)
  1477. certMgr = oldCertMgr
  1478. }
  1479. func TestMisc(t *testing.T) {
  1480. oldCertMgr := certMgr
  1481. certMgr = nil
  1482. err := ReloadCertificateMgr()
  1483. assert.Nil(t, err)
  1484. val := getConfigPath("", ".")
  1485. assert.Empty(t, val)
  1486. certMgr = oldCertMgr
  1487. }