common_test.go 57 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858
  1. // Copyright (C) 2019 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 common
  15. import (
  16. "crypto/tls"
  17. "encoding/json"
  18. "fmt"
  19. "net"
  20. "os"
  21. "os/exec"
  22. "path/filepath"
  23. "runtime"
  24. "sync"
  25. "testing"
  26. "time"
  27. "github.com/alexedwards/argon2id"
  28. "github.com/pires/go-proxyproto"
  29. "github.com/sftpgo/sdk"
  30. "github.com/stretchr/testify/assert"
  31. "github.com/stretchr/testify/require"
  32. "golang.org/x/crypto/bcrypt"
  33. "github.com/drakkan/sftpgo/v2/internal/dataprovider"
  34. "github.com/drakkan/sftpgo/v2/internal/kms"
  35. "github.com/drakkan/sftpgo/v2/internal/plugin"
  36. "github.com/drakkan/sftpgo/v2/internal/util"
  37. "github.com/drakkan/sftpgo/v2/internal/vfs"
  38. )
  39. const (
  40. logSenderTest = "common_test"
  41. httpAddr = "127.0.0.1:9999"
  42. osWindows = "windows"
  43. userTestUsername = "common_test_username"
  44. )
  45. var (
  46. configDir = filepath.Join(".", "..", "..")
  47. )
  48. type fakeConnection struct {
  49. *BaseConnection
  50. command string
  51. }
  52. func (c *fakeConnection) AddUser(user dataprovider.User) error {
  53. _, err := user.GetFilesystem(c.GetID())
  54. if err != nil {
  55. return err
  56. }
  57. c.BaseConnection.User = user
  58. return nil
  59. }
  60. func (c *fakeConnection) Disconnect() error {
  61. Connections.Remove(c.GetID())
  62. return nil
  63. }
  64. func (c *fakeConnection) GetClientVersion() string {
  65. return ""
  66. }
  67. func (c *fakeConnection) GetCommand() string {
  68. return c.command
  69. }
  70. func (c *fakeConnection) GetLocalAddress() string {
  71. return ""
  72. }
  73. func (c *fakeConnection) GetRemoteAddress() string {
  74. return ""
  75. }
  76. type customNetConn struct {
  77. net.Conn
  78. id string
  79. isClosed bool
  80. }
  81. func (c *customNetConn) Close() error {
  82. Connections.RemoveSSHConnection(c.id)
  83. c.isClosed = true
  84. return c.Conn.Close()
  85. }
  86. func TestConnections(t *testing.T) {
  87. c1 := &fakeConnection{
  88. BaseConnection: NewBaseConnection("id1", ProtocolSFTP, "", "", dataprovider.User{
  89. BaseUser: sdk.BaseUser{
  90. Username: userTestUsername,
  91. },
  92. }),
  93. }
  94. c2 := &fakeConnection{
  95. BaseConnection: NewBaseConnection("id2", ProtocolSFTP, "", "", dataprovider.User{
  96. BaseUser: sdk.BaseUser{
  97. Username: userTestUsername,
  98. },
  99. }),
  100. }
  101. c3 := &fakeConnection{
  102. BaseConnection: NewBaseConnection("id3", ProtocolSFTP, "", "", dataprovider.User{
  103. BaseUser: sdk.BaseUser{
  104. Username: userTestUsername,
  105. },
  106. }),
  107. }
  108. c4 := &fakeConnection{
  109. BaseConnection: NewBaseConnection("id4", ProtocolSFTP, "", "", dataprovider.User{
  110. BaseUser: sdk.BaseUser{
  111. Username: userTestUsername,
  112. },
  113. }),
  114. }
  115. assert.Equal(t, "SFTP_id1", c1.GetID())
  116. assert.Equal(t, "SFTP_id2", c2.GetID())
  117. assert.Equal(t, "SFTP_id3", c3.GetID())
  118. assert.Equal(t, "SFTP_id4", c4.GetID())
  119. err := Connections.Add(c1)
  120. assert.NoError(t, err)
  121. err = Connections.Add(c2)
  122. assert.NoError(t, err)
  123. err = Connections.Add(c3)
  124. assert.NoError(t, err)
  125. err = Connections.Add(c4)
  126. assert.NoError(t, err)
  127. Connections.RLock()
  128. assert.Len(t, Connections.connections, 4)
  129. assert.Len(t, Connections.mapping, 4)
  130. _, ok := Connections.mapping[c1.GetID()]
  131. assert.True(t, ok)
  132. assert.Equal(t, 0, Connections.mapping[c1.GetID()])
  133. assert.Equal(t, 1, Connections.mapping[c2.GetID()])
  134. assert.Equal(t, 2, Connections.mapping[c3.GetID()])
  135. assert.Equal(t, 3, Connections.mapping[c4.GetID()])
  136. Connections.RUnlock()
  137. c2 = &fakeConnection{
  138. BaseConnection: NewBaseConnection("id2", ProtocolSFTP, "", "", dataprovider.User{
  139. BaseUser: sdk.BaseUser{
  140. Username: userTestUsername + "_mod",
  141. },
  142. }),
  143. }
  144. err = Connections.Swap(c2)
  145. assert.NoError(t, err)
  146. Connections.RLock()
  147. assert.Len(t, Connections.connections, 4)
  148. assert.Len(t, Connections.mapping, 4)
  149. _, ok = Connections.mapping[c1.GetID()]
  150. assert.True(t, ok)
  151. assert.Equal(t, 0, Connections.mapping[c1.GetID()])
  152. assert.Equal(t, 1, Connections.mapping[c2.GetID()])
  153. assert.Equal(t, 2, Connections.mapping[c3.GetID()])
  154. assert.Equal(t, 3, Connections.mapping[c4.GetID()])
  155. assert.Equal(t, userTestUsername+"_mod", Connections.connections[1].GetUsername())
  156. Connections.RUnlock()
  157. Connections.Remove(c2.GetID())
  158. Connections.RLock()
  159. assert.Len(t, Connections.connections, 3)
  160. assert.Len(t, Connections.mapping, 3)
  161. _, ok = Connections.mapping[c1.GetID()]
  162. assert.True(t, ok)
  163. assert.Equal(t, 0, Connections.mapping[c1.GetID()])
  164. assert.Equal(t, 1, Connections.mapping[c4.GetID()])
  165. assert.Equal(t, 2, Connections.mapping[c3.GetID()])
  166. Connections.RUnlock()
  167. Connections.Remove(c3.GetID())
  168. Connections.RLock()
  169. assert.Len(t, Connections.connections, 2)
  170. assert.Len(t, Connections.mapping, 2)
  171. _, ok = Connections.mapping[c1.GetID()]
  172. assert.True(t, ok)
  173. assert.Equal(t, 0, Connections.mapping[c1.GetID()])
  174. assert.Equal(t, 1, Connections.mapping[c4.GetID()])
  175. Connections.RUnlock()
  176. Connections.Remove(c1.GetID())
  177. Connections.RLock()
  178. assert.Len(t, Connections.connections, 1)
  179. assert.Len(t, Connections.mapping, 1)
  180. _, ok = Connections.mapping[c4.GetID()]
  181. assert.True(t, ok)
  182. assert.Equal(t, 0, Connections.mapping[c4.GetID()])
  183. Connections.RUnlock()
  184. Connections.Remove(c4.GetID())
  185. Connections.RLock()
  186. assert.Len(t, Connections.connections, 0)
  187. assert.Len(t, Connections.mapping, 0)
  188. Connections.RUnlock()
  189. }
  190. func TestInitializationProxyErrors(t *testing.T) {
  191. configCopy := Config
  192. c := Configuration{
  193. ProxyProtocol: 1,
  194. ProxyAllowed: []string{"1.1.1.1111"},
  195. }
  196. err := Initialize(c, 0)
  197. if assert.Error(t, err) {
  198. assert.Contains(t, err.Error(), "invalid proxy allowed")
  199. }
  200. c.ProxyAllowed = nil
  201. c.ProxySkipped = []string{"invalid"}
  202. err = Initialize(c, 0)
  203. if assert.Error(t, err) {
  204. assert.Contains(t, err.Error(), "invalid proxy skipped")
  205. }
  206. c.ProxyAllowed = []string{"1.1.1.1"}
  207. c.ProxySkipped = []string{"2.2.2.2", "10.8.0.0/24"}
  208. err = Initialize(c, 0)
  209. assert.NoError(t, err)
  210. assert.Len(t, Config.proxyAllowed, 1)
  211. assert.Len(t, Config.proxySkipped, 2)
  212. Config = configCopy
  213. assert.Equal(t, 0, Config.ProxyProtocol)
  214. assert.Len(t, Config.proxyAllowed, 0)
  215. assert.Len(t, Config.proxySkipped, 0)
  216. }
  217. func TestInitializationClosedProvider(t *testing.T) {
  218. configCopy := Config
  219. providerConf := dataprovider.GetProviderConfig()
  220. err := dataprovider.Close()
  221. assert.NoError(t, err)
  222. config := Configuration{
  223. AllowListStatus: 1,
  224. }
  225. err = Initialize(config, 0)
  226. if assert.Error(t, err) {
  227. assert.Contains(t, err.Error(), "unable to initialize the allow list")
  228. }
  229. config.AllowListStatus = 0
  230. config.RateLimitersConfig = []RateLimiterConfig{
  231. {
  232. Average: 100,
  233. Period: 1000,
  234. Burst: 5,
  235. Type: int(rateLimiterTypeGlobal),
  236. Protocols: rateLimiterProtocolValues,
  237. },
  238. }
  239. err = Initialize(config, 0)
  240. if assert.Error(t, err) {
  241. assert.Contains(t, err.Error(), "unable to initialize ratelimiters list")
  242. }
  243. config.RateLimitersConfig = nil
  244. config.DefenderConfig = DefenderConfig{
  245. Enabled: true,
  246. Driver: DefenderDriverProvider,
  247. BanTime: 10,
  248. BanTimeIncrement: 50,
  249. Threshold: 10,
  250. ScoreInvalid: 2,
  251. ScoreValid: 1,
  252. ScoreNoAuth: 2,
  253. ObservationTime: 15,
  254. EntriesSoftLimit: 100,
  255. EntriesHardLimit: 150,
  256. }
  257. err = Initialize(config, 0)
  258. if assert.Error(t, err) {
  259. assert.Contains(t, err.Error(), "defender initialization error")
  260. }
  261. config.DefenderConfig.Driver = DefenderDriverMemory
  262. err = Initialize(config, 0)
  263. if assert.Error(t, err) {
  264. assert.Contains(t, err.Error(), "defender initialization error")
  265. }
  266. err = dataprovider.Initialize(providerConf, configDir, true)
  267. assert.NoError(t, err)
  268. Config = configCopy
  269. }
  270. func TestSSHConnections(t *testing.T) {
  271. conn1, conn2 := net.Pipe()
  272. now := time.Now()
  273. sshConn1 := NewSSHConnection("id1", conn1)
  274. sshConn2 := NewSSHConnection("id2", conn2)
  275. sshConn3 := NewSSHConnection("id3", conn2)
  276. assert.Equal(t, "id1", sshConn1.GetID())
  277. assert.Equal(t, "id2", sshConn2.GetID())
  278. assert.Equal(t, "id3", sshConn3.GetID())
  279. sshConn1.UpdateLastActivity()
  280. assert.GreaterOrEqual(t, sshConn1.GetLastActivity().UnixNano(), now.UnixNano())
  281. Connections.AddSSHConnection(sshConn1)
  282. Connections.AddSSHConnection(sshConn2)
  283. Connections.AddSSHConnection(sshConn3)
  284. Connections.RLock()
  285. assert.Len(t, Connections.sshConnections, 3)
  286. _, ok := Connections.sshMapping[sshConn1.GetID()]
  287. assert.True(t, ok)
  288. assert.Equal(t, 0, Connections.sshMapping[sshConn1.GetID()])
  289. assert.Equal(t, 1, Connections.sshMapping[sshConn2.GetID()])
  290. assert.Equal(t, 2, Connections.sshMapping[sshConn3.GetID()])
  291. Connections.RUnlock()
  292. Connections.RemoveSSHConnection(sshConn1.id)
  293. Connections.RLock()
  294. assert.Len(t, Connections.sshConnections, 2)
  295. assert.Equal(t, sshConn3.id, Connections.sshConnections[0].id)
  296. assert.Equal(t, sshConn2.id, Connections.sshConnections[1].id)
  297. _, ok = Connections.sshMapping[sshConn3.GetID()]
  298. assert.True(t, ok)
  299. assert.Equal(t, 0, Connections.sshMapping[sshConn3.GetID()])
  300. assert.Equal(t, 1, Connections.sshMapping[sshConn2.GetID()])
  301. Connections.RUnlock()
  302. Connections.RemoveSSHConnection(sshConn1.id)
  303. Connections.RLock()
  304. assert.Len(t, Connections.sshConnections, 2)
  305. assert.Equal(t, sshConn3.id, Connections.sshConnections[0].id)
  306. assert.Equal(t, sshConn2.id, Connections.sshConnections[1].id)
  307. _, ok = Connections.sshMapping[sshConn3.GetID()]
  308. assert.True(t, ok)
  309. assert.Equal(t, 0, Connections.sshMapping[sshConn3.GetID()])
  310. assert.Equal(t, 1, Connections.sshMapping[sshConn2.GetID()])
  311. Connections.RUnlock()
  312. Connections.RemoveSSHConnection(sshConn2.id)
  313. Connections.RLock()
  314. assert.Len(t, Connections.sshConnections, 1)
  315. assert.Equal(t, sshConn3.id, Connections.sshConnections[0].id)
  316. _, ok = Connections.sshMapping[sshConn3.GetID()]
  317. assert.True(t, ok)
  318. assert.Equal(t, 0, Connections.sshMapping[sshConn3.GetID()])
  319. Connections.RUnlock()
  320. Connections.RemoveSSHConnection(sshConn3.id)
  321. Connections.RLock()
  322. assert.Len(t, Connections.sshConnections, 0)
  323. assert.Len(t, Connections.sshMapping, 0)
  324. Connections.RUnlock()
  325. assert.NoError(t, sshConn1.Close())
  326. assert.NoError(t, sshConn2.Close())
  327. assert.NoError(t, sshConn3.Close())
  328. }
  329. func TestDefenderIntegration(t *testing.T) {
  330. // by default defender is nil
  331. configCopy := Config
  332. wdPath, err := os.Getwd()
  333. require.NoError(t, err)
  334. pluginsConfig := []plugin.Config{
  335. {
  336. Type: "ipfilter",
  337. Cmd: filepath.Join(wdPath, "..", "..", "tests", "ipfilter", "ipfilter"),
  338. AutoMTLS: true,
  339. },
  340. }
  341. if runtime.GOOS == osWindows {
  342. pluginsConfig[0].Cmd += ".exe"
  343. }
  344. err = plugin.Initialize(pluginsConfig, "debug")
  345. require.NoError(t, err)
  346. ip := "127.1.1.1"
  347. assert.Nil(t, Reload())
  348. // 192.168.1.12 is banned from the ipfilter plugin
  349. assert.True(t, IsBanned("192.168.1.12", ProtocolFTP))
  350. AddDefenderEvent(ip, ProtocolFTP, HostEventNoLoginTried)
  351. assert.False(t, IsBanned(ip, ProtocolFTP))
  352. banTime, err := GetDefenderBanTime(ip)
  353. assert.NoError(t, err)
  354. assert.Nil(t, banTime)
  355. assert.False(t, DeleteDefenderHost(ip))
  356. score, err := GetDefenderScore(ip)
  357. assert.NoError(t, err)
  358. assert.Equal(t, 0, score)
  359. _, err = GetDefenderHost(ip)
  360. assert.Error(t, err)
  361. hosts, err := GetDefenderHosts()
  362. assert.NoError(t, err)
  363. assert.Nil(t, hosts)
  364. Config.DefenderConfig = DefenderConfig{
  365. Enabled: true,
  366. Driver: DefenderDriverProvider,
  367. BanTime: 10,
  368. BanTimeIncrement: 50,
  369. Threshold: 0,
  370. ScoreInvalid: 2,
  371. ScoreValid: 1,
  372. ScoreNoAuth: 2,
  373. ObservationTime: 15,
  374. EntriesSoftLimit: 100,
  375. EntriesHardLimit: 150,
  376. }
  377. err = Initialize(Config, 0)
  378. // ScoreInvalid cannot be greater than threshold
  379. assert.Error(t, err)
  380. Config.DefenderConfig.Driver = "unsupported"
  381. err = Initialize(Config, 0)
  382. if assert.Error(t, err) {
  383. assert.Contains(t, err.Error(), "unsupported defender driver")
  384. }
  385. Config.DefenderConfig.Driver = DefenderDriverMemory
  386. err = Initialize(Config, 0)
  387. // ScoreInvalid cannot be greater than threshold
  388. assert.Error(t, err)
  389. Config.DefenderConfig.Threshold = 3
  390. err = Initialize(Config, 0)
  391. assert.NoError(t, err)
  392. assert.Nil(t, Reload())
  393. AddDefenderEvent(ip, ProtocolSSH, HostEventNoLoginTried)
  394. assert.False(t, IsBanned(ip, ProtocolSSH))
  395. score, err = GetDefenderScore(ip)
  396. assert.NoError(t, err)
  397. assert.Equal(t, 2, score)
  398. entry, err := GetDefenderHost(ip)
  399. assert.NoError(t, err)
  400. asJSON, err := json.Marshal(&entry)
  401. assert.NoError(t, err)
  402. assert.Equal(t, `{"id":"3132372e312e312e31","ip":"127.1.1.1","score":2}`, string(asJSON), "entry %v", entry)
  403. assert.True(t, DeleteDefenderHost(ip))
  404. banTime, err = GetDefenderBanTime(ip)
  405. assert.NoError(t, err)
  406. assert.Nil(t, banTime)
  407. AddDefenderEvent(ip, ProtocolHTTP, HostEventLoginFailed)
  408. AddDefenderEvent(ip, ProtocolHTTP, HostEventNoLoginTried)
  409. assert.True(t, IsBanned(ip, ProtocolHTTP))
  410. score, err = GetDefenderScore(ip)
  411. assert.NoError(t, err)
  412. assert.Equal(t, 0, score)
  413. banTime, err = GetDefenderBanTime(ip)
  414. assert.NoError(t, err)
  415. assert.NotNil(t, banTime)
  416. hosts, err = GetDefenderHosts()
  417. assert.NoError(t, err)
  418. assert.Len(t, hosts, 1)
  419. entry, err = GetDefenderHost(ip)
  420. assert.NoError(t, err)
  421. assert.False(t, entry.BanTime.IsZero())
  422. assert.True(t, DeleteDefenderHost(ip))
  423. hosts, err = GetDefenderHosts()
  424. assert.NoError(t, err)
  425. assert.Len(t, hosts, 0)
  426. banTime, err = GetDefenderBanTime(ip)
  427. assert.NoError(t, err)
  428. assert.Nil(t, banTime)
  429. assert.False(t, DeleteDefenderHost(ip))
  430. Config = configCopy
  431. }
  432. func TestRateLimitersIntegration(t *testing.T) {
  433. configCopy := Config
  434. enabled, protocols := Config.GetRateLimitersStatus()
  435. assert.False(t, enabled)
  436. assert.Len(t, protocols, 0)
  437. entries := []dataprovider.IPListEntry{
  438. {
  439. IPOrNet: "172.16.24.7/32",
  440. Type: dataprovider.IPListTypeRateLimiterSafeList,
  441. Mode: dataprovider.ListModeAllow,
  442. },
  443. {
  444. IPOrNet: "172.16.0.0/16",
  445. Type: dataprovider.IPListTypeRateLimiterSafeList,
  446. Mode: dataprovider.ListModeAllow,
  447. },
  448. }
  449. for idx := range entries {
  450. e := entries[idx]
  451. err := dataprovider.AddIPListEntry(&e, "", "", "")
  452. assert.NoError(t, err)
  453. }
  454. Config.RateLimitersConfig = []RateLimiterConfig{
  455. {
  456. Average: 100,
  457. Period: 10,
  458. Burst: 5,
  459. Type: int(rateLimiterTypeGlobal),
  460. Protocols: rateLimiterProtocolValues,
  461. },
  462. {
  463. Average: 1,
  464. Period: 1000,
  465. Burst: 1,
  466. Type: int(rateLimiterTypeSource),
  467. Protocols: []string{ProtocolWebDAV, ProtocolWebDAV, ProtocolFTP},
  468. GenerateDefenderEvents: true,
  469. EntriesSoftLimit: 100,
  470. EntriesHardLimit: 150,
  471. },
  472. }
  473. err := Initialize(Config, 0)
  474. assert.Error(t, err)
  475. Config.RateLimitersConfig[0].Period = 1000
  476. err = Initialize(Config, 0)
  477. assert.NoError(t, err)
  478. assert.NotNil(t, Config.rateLimitersList)
  479. assert.Len(t, rateLimiters, 4)
  480. assert.Len(t, rateLimiters[ProtocolSSH], 1)
  481. assert.Len(t, rateLimiters[ProtocolFTP], 2)
  482. assert.Len(t, rateLimiters[ProtocolWebDAV], 2)
  483. assert.Len(t, rateLimiters[ProtocolHTTP], 1)
  484. enabled, protocols = Config.GetRateLimitersStatus()
  485. assert.True(t, enabled)
  486. assert.Len(t, protocols, 4)
  487. assert.Contains(t, protocols, ProtocolFTP)
  488. assert.Contains(t, protocols, ProtocolSSH)
  489. assert.Contains(t, protocols, ProtocolHTTP)
  490. assert.Contains(t, protocols, ProtocolWebDAV)
  491. source1 := "127.1.1.1"
  492. source2 := "127.1.1.2"
  493. source3 := "172.16.24.7" // in safelist
  494. _, err = LimitRate(ProtocolSSH, source1)
  495. assert.NoError(t, err)
  496. _, err = LimitRate(ProtocolFTP, source1)
  497. assert.NoError(t, err)
  498. // sleep to allow the add configured burst to the token.
  499. // This sleep is not enough to add the per-source burst
  500. time.Sleep(20 * time.Millisecond)
  501. _, err = LimitRate(ProtocolWebDAV, source2)
  502. assert.NoError(t, err)
  503. _, err = LimitRate(ProtocolFTP, source1)
  504. assert.Error(t, err)
  505. _, err = LimitRate(ProtocolWebDAV, source2)
  506. assert.Error(t, err)
  507. _, err = LimitRate(ProtocolSSH, source1)
  508. assert.NoError(t, err)
  509. _, err = LimitRate(ProtocolSSH, source2)
  510. assert.NoError(t, err)
  511. for i := 0; i < 10; i++ {
  512. _, err = LimitRate(ProtocolWebDAV, source3)
  513. assert.NoError(t, err)
  514. }
  515. for _, e := range entries {
  516. err := dataprovider.DeleteIPListEntry(e.IPOrNet, e.Type, "", "", "")
  517. assert.NoError(t, err)
  518. }
  519. assert.Nil(t, configCopy.rateLimitersList)
  520. Config = configCopy
  521. }
  522. func TestUserMaxSessions(t *testing.T) {
  523. c := NewBaseConnection("id", ProtocolSFTP, "", "", dataprovider.User{
  524. BaseUser: sdk.BaseUser{
  525. Username: userTestUsername,
  526. MaxSessions: 1,
  527. },
  528. })
  529. fakeConn := &fakeConnection{
  530. BaseConnection: c,
  531. }
  532. err := Connections.Add(fakeConn)
  533. assert.NoError(t, err)
  534. err = Connections.Add(fakeConn)
  535. assert.Error(t, err)
  536. err = Connections.Swap(fakeConn)
  537. assert.NoError(t, err)
  538. Connections.Remove(fakeConn.GetID())
  539. Connections.Lock()
  540. Connections.removeUserConnection(userTestUsername)
  541. Connections.Unlock()
  542. assert.Len(t, Connections.GetStats(""), 0)
  543. }
  544. func TestMaxConnections(t *testing.T) {
  545. oldValue := Config.MaxTotalConnections
  546. perHost := Config.MaxPerHostConnections
  547. Config.MaxPerHostConnections = 0
  548. ipAddr := "192.168.7.8"
  549. assert.NoError(t, Connections.IsNewConnectionAllowed(ipAddr, ProtocolFTP))
  550. Config.MaxTotalConnections = 1
  551. Config.MaxPerHostConnections = perHost
  552. assert.NoError(t, Connections.IsNewConnectionAllowed(ipAddr, ProtocolHTTP))
  553. c := NewBaseConnection("id", ProtocolSFTP, "", "", dataprovider.User{})
  554. fakeConn := &fakeConnection{
  555. BaseConnection: c,
  556. }
  557. err := Connections.Add(fakeConn)
  558. assert.NoError(t, err)
  559. assert.Len(t, Connections.GetStats(""), 1)
  560. assert.Error(t, Connections.IsNewConnectionAllowed(ipAddr, ProtocolSSH))
  561. res := Connections.Close(fakeConn.GetID(), "")
  562. assert.True(t, res)
  563. assert.Eventually(t, func() bool { return len(Connections.GetStats("")) == 0 }, 300*time.Millisecond, 50*time.Millisecond)
  564. assert.NoError(t, Connections.IsNewConnectionAllowed(ipAddr, ProtocolSSH))
  565. Connections.AddClientConnection(ipAddr)
  566. Connections.AddClientConnection(ipAddr)
  567. assert.Error(t, Connections.IsNewConnectionAllowed(ipAddr, ProtocolSSH))
  568. Connections.RemoveClientConnection(ipAddr)
  569. assert.NoError(t, Connections.IsNewConnectionAllowed(ipAddr, ProtocolWebDAV))
  570. Connections.RemoveClientConnection(ipAddr)
  571. Config.MaxTotalConnections = oldValue
  572. }
  573. func TestConnectionRoles(t *testing.T) {
  574. username := "testUsername"
  575. role1 := "testRole1"
  576. role2 := "testRole2"
  577. c := NewBaseConnection("id", ProtocolSFTP, "", "", dataprovider.User{
  578. BaseUser: sdk.BaseUser{
  579. Username: username,
  580. Role: role1,
  581. },
  582. })
  583. fakeConn := &fakeConnection{
  584. BaseConnection: c,
  585. }
  586. err := Connections.Add(fakeConn)
  587. assert.NoError(t, err)
  588. assert.Len(t, Connections.GetStats(""), 1)
  589. assert.Len(t, Connections.GetStats(role1), 1)
  590. assert.Len(t, Connections.GetStats(role2), 0)
  591. res := Connections.Close(fakeConn.GetID(), role2)
  592. assert.False(t, res)
  593. assert.Len(t, Connections.GetStats(""), 1)
  594. res = Connections.Close(fakeConn.GetID(), role1)
  595. assert.True(t, res)
  596. assert.Eventually(t, func() bool { return len(Connections.GetStats("")) == 0 }, 300*time.Millisecond, 50*time.Millisecond)
  597. }
  598. func TestMaxConnectionPerHost(t *testing.T) {
  599. defender, err := newInMemoryDefender(&DefenderConfig{
  600. Enabled: true,
  601. Driver: DefenderDriverMemory,
  602. BanTime: 30,
  603. BanTimeIncrement: 50,
  604. Threshold: 15,
  605. ScoreInvalid: 2,
  606. ScoreValid: 1,
  607. ScoreLimitExceeded: 3,
  608. ObservationTime: 30,
  609. EntriesSoftLimit: 100,
  610. EntriesHardLimit: 150,
  611. })
  612. require.NoError(t, err)
  613. oldMaxPerHostConn := Config.MaxPerHostConnections
  614. oldDefender := Config.defender
  615. Config.MaxPerHostConnections = 2
  616. Config.defender = defender
  617. ipAddr := "192.168.9.9"
  618. Connections.AddClientConnection(ipAddr)
  619. assert.NoError(t, Connections.IsNewConnectionAllowed(ipAddr, ProtocolSSH))
  620. Connections.AddClientConnection(ipAddr)
  621. assert.NoError(t, Connections.IsNewConnectionAllowed(ipAddr, ProtocolWebDAV))
  622. Connections.AddClientConnection(ipAddr)
  623. assert.Error(t, Connections.IsNewConnectionAllowed(ipAddr, ProtocolFTP))
  624. assert.Equal(t, int32(3), Connections.GetClientConnections())
  625. // Add the IP to the defender safe list
  626. entry := dataprovider.IPListEntry{
  627. IPOrNet: ipAddr,
  628. Type: dataprovider.IPListTypeDefender,
  629. Mode: dataprovider.ListModeAllow,
  630. }
  631. err = dataprovider.AddIPListEntry(&entry, "", "", "")
  632. assert.NoError(t, err)
  633. Connections.AddClientConnection(ipAddr)
  634. assert.NoError(t, Connections.IsNewConnectionAllowed(ipAddr, ProtocolSSH))
  635. err = dataprovider.DeleteIPListEntry(entry.IPOrNet, dataprovider.IPListTypeDefender, "", "", "")
  636. assert.NoError(t, err)
  637. Connections.RemoveClientConnection(ipAddr)
  638. Connections.RemoveClientConnection(ipAddr)
  639. Connections.RemoveClientConnection(ipAddr)
  640. Connections.RemoveClientConnection(ipAddr)
  641. assert.Equal(t, int32(0), Connections.GetClientConnections())
  642. Config.MaxPerHostConnections = oldMaxPerHostConn
  643. Config.defender = oldDefender
  644. }
  645. func TestIdleConnections(t *testing.T) {
  646. configCopy := Config
  647. Config.IdleTimeout = 1
  648. err := Initialize(Config, 0)
  649. assert.NoError(t, err)
  650. conn1, conn2 := net.Pipe()
  651. customConn1 := &customNetConn{
  652. Conn: conn1,
  653. id: "id1",
  654. }
  655. customConn2 := &customNetConn{
  656. Conn: conn2,
  657. id: "id2",
  658. }
  659. sshConn1 := NewSSHConnection(customConn1.id, customConn1)
  660. sshConn2 := NewSSHConnection(customConn2.id, customConn2)
  661. username := "test_user"
  662. user := dataprovider.User{
  663. BaseUser: sdk.BaseUser{
  664. Username: username,
  665. Status: 1,
  666. },
  667. }
  668. c := NewBaseConnection(sshConn1.id+"_1", ProtocolSFTP, "", "", user)
  669. c.lastActivity.Store(time.Now().Add(-24 * time.Hour).UnixNano())
  670. fakeConn := &fakeConnection{
  671. BaseConnection: c,
  672. }
  673. // both ssh connections are expired but they should get removed only
  674. // if there is no associated connection
  675. sshConn1.lastActivity.Store(c.lastActivity.Load())
  676. sshConn2.lastActivity.Store(c.lastActivity.Load())
  677. Connections.AddSSHConnection(sshConn1)
  678. err = Connections.Add(fakeConn)
  679. assert.NoError(t, err)
  680. assert.Equal(t, Connections.GetActiveSessions(username), 1)
  681. c = NewBaseConnection(sshConn2.id+"_1", ProtocolSSH, "", "", user)
  682. fakeConn = &fakeConnection{
  683. BaseConnection: c,
  684. }
  685. Connections.AddSSHConnection(sshConn2)
  686. err = Connections.Add(fakeConn)
  687. assert.NoError(t, err)
  688. assert.Equal(t, Connections.GetActiveSessions(username), 2)
  689. cFTP := NewBaseConnection("id2", ProtocolFTP, "", "", dataprovider.User{
  690. BaseUser: sdk.BaseUser{
  691. Status: 1,
  692. },
  693. })
  694. cFTP.lastActivity.Store(time.Now().UnixNano())
  695. fakeConn = &fakeConnection{
  696. BaseConnection: cFTP,
  697. }
  698. err = Connections.Add(fakeConn)
  699. assert.NoError(t, err)
  700. // the user is expired, this connection will be removed
  701. cDAV := NewBaseConnection("id3", ProtocolWebDAV, "", "", dataprovider.User{
  702. BaseUser: sdk.BaseUser{
  703. Username: username + "_2",
  704. Status: 1,
  705. ExpirationDate: util.GetTimeAsMsSinceEpoch(time.Now().Add(-24 * time.Hour)),
  706. },
  707. })
  708. cDAV.lastActivity.Store(time.Now().UnixNano())
  709. fakeConn = &fakeConnection{
  710. BaseConnection: cDAV,
  711. }
  712. err = Connections.Add(fakeConn)
  713. assert.NoError(t, err)
  714. assert.Equal(t, 2, Connections.GetActiveSessions(username))
  715. assert.Len(t, Connections.GetStats(""), 4)
  716. Connections.RLock()
  717. assert.Len(t, Connections.sshConnections, 2)
  718. Connections.RUnlock()
  719. startPeriodicChecks(100*time.Millisecond, 0)
  720. assert.Eventually(t, func() bool { return Connections.GetActiveSessions(username) == 1 }, 2*time.Second, 200*time.Millisecond)
  721. assert.Eventually(t, func() bool {
  722. Connections.RLock()
  723. defer Connections.RUnlock()
  724. return len(Connections.sshConnections) == 1
  725. }, 1*time.Second, 200*time.Millisecond)
  726. stopEventScheduler()
  727. assert.Len(t, Connections.GetStats(""), 2)
  728. c.lastActivity.Store(time.Now().Add(-24 * time.Hour).UnixNano())
  729. cFTP.lastActivity.Store(time.Now().Add(-24 * time.Hour).UnixNano())
  730. sshConn2.lastActivity.Store(c.lastActivity.Load())
  731. startPeriodicChecks(100*time.Millisecond, 1)
  732. assert.Eventually(t, func() bool { return len(Connections.GetStats("")) == 0 }, 2*time.Second, 200*time.Millisecond)
  733. assert.Eventually(t, func() bool {
  734. Connections.RLock()
  735. defer Connections.RUnlock()
  736. return len(Connections.sshConnections) == 0
  737. }, 1*time.Second, 200*time.Millisecond)
  738. assert.Equal(t, int32(0), Connections.GetClientConnections())
  739. stopEventScheduler()
  740. assert.True(t, customConn1.isClosed)
  741. assert.True(t, customConn2.isClosed)
  742. Config = configCopy
  743. }
  744. func TestCloseConnection(t *testing.T) {
  745. c := NewBaseConnection("id", ProtocolSFTP, "", "", dataprovider.User{})
  746. fakeConn := &fakeConnection{
  747. BaseConnection: c,
  748. }
  749. assert.NoError(t, Connections.IsNewConnectionAllowed("127.0.0.1", ProtocolHTTP))
  750. err := Connections.Add(fakeConn)
  751. assert.NoError(t, err)
  752. assert.Len(t, Connections.GetStats(""), 1)
  753. res := Connections.Close(fakeConn.GetID(), "")
  754. assert.True(t, res)
  755. assert.Eventually(t, func() bool { return len(Connections.GetStats("")) == 0 }, 300*time.Millisecond, 50*time.Millisecond)
  756. res = Connections.Close(fakeConn.GetID(), "")
  757. assert.False(t, res)
  758. Connections.Remove(fakeConn.GetID())
  759. }
  760. func TestSwapConnection(t *testing.T) {
  761. c := NewBaseConnection("id", ProtocolFTP, "", "", dataprovider.User{})
  762. fakeConn := &fakeConnection{
  763. BaseConnection: c,
  764. }
  765. err := Connections.Add(fakeConn)
  766. assert.NoError(t, err)
  767. if assert.Len(t, Connections.GetStats(""), 1) {
  768. assert.Equal(t, "", Connections.GetStats("")[0].Username)
  769. }
  770. c = NewBaseConnection("id", ProtocolFTP, "", "", dataprovider.User{
  771. BaseUser: sdk.BaseUser{
  772. Username: userTestUsername,
  773. MaxSessions: 1,
  774. },
  775. })
  776. fakeConn = &fakeConnection{
  777. BaseConnection: c,
  778. }
  779. c1 := NewBaseConnection("id1", ProtocolFTP, "", "", dataprovider.User{
  780. BaseUser: sdk.BaseUser{
  781. Username: userTestUsername,
  782. },
  783. })
  784. fakeConn1 := &fakeConnection{
  785. BaseConnection: c1,
  786. }
  787. err = Connections.Add(fakeConn1)
  788. assert.NoError(t, err)
  789. err = Connections.Swap(fakeConn)
  790. assert.Error(t, err)
  791. Connections.Remove(fakeConn1.ID)
  792. err = Connections.Swap(fakeConn)
  793. assert.NoError(t, err)
  794. if assert.Len(t, Connections.GetStats(""), 1) {
  795. assert.Equal(t, userTestUsername, Connections.GetStats("")[0].Username)
  796. }
  797. res := Connections.Close(fakeConn.GetID(), "")
  798. assert.True(t, res)
  799. assert.Eventually(t, func() bool { return len(Connections.GetStats("")) == 0 }, 300*time.Millisecond, 50*time.Millisecond)
  800. err = Connections.Swap(fakeConn)
  801. assert.Error(t, err)
  802. }
  803. func TestAtomicUpload(t *testing.T) {
  804. configCopy := Config
  805. Config.UploadMode = UploadModeStandard
  806. assert.False(t, Config.IsAtomicUploadEnabled())
  807. Config.UploadMode = UploadModeAtomic
  808. assert.True(t, Config.IsAtomicUploadEnabled())
  809. Config.UploadMode = UploadModeAtomicWithResume
  810. assert.True(t, Config.IsAtomicUploadEnabled())
  811. Config = configCopy
  812. }
  813. func TestConnectionStatus(t *testing.T) {
  814. username := "test_user"
  815. user := dataprovider.User{
  816. BaseUser: sdk.BaseUser{
  817. Username: username,
  818. },
  819. }
  820. fs := vfs.NewOsFs("", os.TempDir(), "", nil)
  821. c1 := NewBaseConnection("id1", ProtocolSFTP, "", "", user)
  822. fakeConn1 := &fakeConnection{
  823. BaseConnection: c1,
  824. }
  825. t1 := NewBaseTransfer(nil, c1, nil, "/p1", "/p1", "/r1", TransferUpload, 0, 0, 0, 0, true, fs, dataprovider.TransferQuota{})
  826. t1.BytesReceived.Store(123)
  827. t2 := NewBaseTransfer(nil, c1, nil, "/p2", "/p2", "/r2", TransferDownload, 0, 0, 0, 0, true, fs, dataprovider.TransferQuota{})
  828. t2.BytesSent.Store(456)
  829. c2 := NewBaseConnection("id2", ProtocolSSH, "", "", user)
  830. fakeConn2 := &fakeConnection{
  831. BaseConnection: c2,
  832. command: "md5sum",
  833. }
  834. c3 := NewBaseConnection("id3", ProtocolWebDAV, "", "", user)
  835. fakeConn3 := &fakeConnection{
  836. BaseConnection: c3,
  837. command: "PROPFIND",
  838. }
  839. t3 := NewBaseTransfer(nil, c3, nil, "/p2", "/p2", "/r2", TransferDownload, 0, 0, 0, 0, true, fs, dataprovider.TransferQuota{})
  840. err := Connections.Add(fakeConn1)
  841. assert.NoError(t, err)
  842. err = Connections.Add(fakeConn2)
  843. assert.NoError(t, err)
  844. err = Connections.Add(fakeConn3)
  845. assert.NoError(t, err)
  846. stats := Connections.GetStats("")
  847. assert.Len(t, stats, 3)
  848. for _, stat := range stats {
  849. assert.Equal(t, stat.Username, username)
  850. if stat.ConnectionID == "SFTP_id1" {
  851. assert.Len(t, stat.Transfers, 2)
  852. } else if stat.ConnectionID == "DAV_id3" {
  853. assert.Len(t, stat.Transfers, 1)
  854. }
  855. }
  856. err = t1.Close()
  857. assert.NoError(t, err)
  858. err = t2.Close()
  859. assert.NoError(t, err)
  860. err = fakeConn3.SignalTransfersAbort()
  861. assert.NoError(t, err)
  862. assert.True(t, t3.AbortTransfer.Load())
  863. err = t3.Close()
  864. assert.NoError(t, err)
  865. err = fakeConn3.SignalTransfersAbort()
  866. assert.Error(t, err)
  867. Connections.Remove(fakeConn1.GetID())
  868. stats = Connections.GetStats("")
  869. assert.Len(t, stats, 2)
  870. assert.Equal(t, fakeConn3.GetID(), stats[0].ConnectionID)
  871. assert.Equal(t, fakeConn2.GetID(), stats[1].ConnectionID)
  872. Connections.Remove(fakeConn2.GetID())
  873. stats = Connections.GetStats("")
  874. assert.Len(t, stats, 1)
  875. assert.Equal(t, fakeConn3.GetID(), stats[0].ConnectionID)
  876. Connections.Remove(fakeConn3.GetID())
  877. stats = Connections.GetStats("")
  878. assert.Len(t, stats, 0)
  879. }
  880. func TestQuotaScans(t *testing.T) {
  881. username := "username"
  882. assert.True(t, QuotaScans.AddUserQuotaScan(username, ""))
  883. assert.False(t, QuotaScans.AddUserQuotaScan(username, ""))
  884. usersScans := QuotaScans.GetUsersQuotaScans("")
  885. if assert.Len(t, usersScans, 1) {
  886. assert.Equal(t, usersScans[0].Username, username)
  887. assert.Equal(t, QuotaScans.UserScans[0].StartTime, usersScans[0].StartTime)
  888. QuotaScans.UserScans[0].StartTime = 0
  889. assert.NotEqual(t, QuotaScans.UserScans[0].StartTime, usersScans[0].StartTime)
  890. }
  891. assert.True(t, QuotaScans.RemoveUserQuotaScan(username))
  892. assert.False(t, QuotaScans.RemoveUserQuotaScan(username))
  893. assert.Len(t, QuotaScans.GetUsersQuotaScans(""), 0)
  894. assert.Len(t, usersScans, 1)
  895. folderName := "folder"
  896. assert.True(t, QuotaScans.AddVFolderQuotaScan(folderName))
  897. assert.False(t, QuotaScans.AddVFolderQuotaScan(folderName))
  898. if assert.Len(t, QuotaScans.GetVFoldersQuotaScans(), 1) {
  899. assert.Equal(t, QuotaScans.GetVFoldersQuotaScans()[0].Name, folderName)
  900. }
  901. assert.True(t, QuotaScans.RemoveVFolderQuotaScan(folderName))
  902. assert.False(t, QuotaScans.RemoveVFolderQuotaScan(folderName))
  903. assert.Len(t, QuotaScans.GetVFoldersQuotaScans(), 0)
  904. }
  905. func TestQuotaScansRole(t *testing.T) {
  906. username := "u"
  907. role1 := "r1"
  908. role2 := "r2"
  909. assert.True(t, QuotaScans.AddUserQuotaScan(username, role1))
  910. assert.False(t, QuotaScans.AddUserQuotaScan(username, ""))
  911. usersScans := QuotaScans.GetUsersQuotaScans("")
  912. assert.Len(t, usersScans, 1)
  913. assert.Empty(t, usersScans[0].Role)
  914. usersScans = QuotaScans.GetUsersQuotaScans(role1)
  915. assert.Len(t, usersScans, 1)
  916. usersScans = QuotaScans.GetUsersQuotaScans(role2)
  917. assert.Len(t, usersScans, 0)
  918. assert.True(t, QuotaScans.RemoveUserQuotaScan(username))
  919. assert.False(t, QuotaScans.RemoveUserQuotaScan(username))
  920. assert.Len(t, QuotaScans.GetUsersQuotaScans(""), 0)
  921. }
  922. func TestProxyPolicy(t *testing.T) {
  923. addr := net.TCPAddr{}
  924. p := getProxyPolicy(nil, nil, proxyproto.IGNORE)
  925. policy, err := p(&addr)
  926. assert.Error(t, err)
  927. assert.Equal(t, proxyproto.REJECT, policy)
  928. ip1 := net.ParseIP("10.8.1.1")
  929. ip2 := net.ParseIP("10.8.1.2")
  930. ip3 := net.ParseIP("10.8.1.3")
  931. allowed, err := util.ParseAllowedIPAndRanges([]string{ip1.String()})
  932. assert.NoError(t, err)
  933. skipped, err := util.ParseAllowedIPAndRanges([]string{ip2.String(), ip3.String()})
  934. assert.NoError(t, err)
  935. p = getProxyPolicy(allowed, skipped, proxyproto.IGNORE)
  936. policy, err = p(&net.TCPAddr{IP: ip1})
  937. assert.NoError(t, err)
  938. assert.Equal(t, proxyproto.USE, policy)
  939. policy, err = p(&net.TCPAddr{IP: ip2})
  940. assert.NoError(t, err)
  941. assert.Equal(t, proxyproto.SKIP, policy)
  942. policy, err = p(&net.TCPAddr{IP: ip3})
  943. assert.NoError(t, err)
  944. assert.Equal(t, proxyproto.SKIP, policy)
  945. policy, err = p(&net.TCPAddr{IP: net.ParseIP("10.8.1.4")})
  946. assert.NoError(t, err)
  947. assert.Equal(t, proxyproto.IGNORE, policy)
  948. p = getProxyPolicy(allowed, skipped, proxyproto.REQUIRE)
  949. policy, err = p(&net.TCPAddr{IP: ip1})
  950. assert.NoError(t, err)
  951. assert.Equal(t, proxyproto.REQUIRE, policy)
  952. policy, err = p(&net.TCPAddr{IP: ip2})
  953. assert.NoError(t, err)
  954. assert.Equal(t, proxyproto.SKIP, policy)
  955. policy, err = p(&net.TCPAddr{IP: ip3})
  956. assert.NoError(t, err)
  957. assert.Equal(t, proxyproto.SKIP, policy)
  958. policy, err = p(&net.TCPAddr{IP: net.ParseIP("10.8.1.5")})
  959. assert.NoError(t, err)
  960. assert.Equal(t, proxyproto.REQUIRE, policy)
  961. }
  962. func TestProxyProtocolVersion(t *testing.T) {
  963. c := Configuration{
  964. ProxyProtocol: 0,
  965. }
  966. _, err := c.GetProxyListener(nil)
  967. if assert.Error(t, err) {
  968. assert.Contains(t, err.Error(), "proxy protocol not configured")
  969. }
  970. c.ProxyProtocol = 1
  971. proxyListener, err := c.GetProxyListener(nil)
  972. assert.NoError(t, err)
  973. assert.NotNil(t, proxyListener.Policy)
  974. c.ProxyProtocol = 2
  975. proxyListener, err = c.GetProxyListener(nil)
  976. assert.NoError(t, err)
  977. assert.NotNil(t, proxyListener.Policy)
  978. }
  979. func TestStartupHook(t *testing.T) {
  980. Config.StartupHook = ""
  981. assert.NoError(t, Config.ExecuteStartupHook())
  982. Config.StartupHook = "http://foo\x7f.com/startup"
  983. assert.Error(t, Config.ExecuteStartupHook())
  984. Config.StartupHook = "http://invalid:5678/"
  985. assert.Error(t, Config.ExecuteStartupHook())
  986. Config.StartupHook = fmt.Sprintf("http://%v", httpAddr)
  987. assert.NoError(t, Config.ExecuteStartupHook())
  988. Config.StartupHook = "invalidhook"
  989. assert.Error(t, Config.ExecuteStartupHook())
  990. if runtime.GOOS != osWindows {
  991. hookCmd, err := exec.LookPath("true")
  992. assert.NoError(t, err)
  993. Config.StartupHook = hookCmd
  994. assert.NoError(t, Config.ExecuteStartupHook())
  995. }
  996. Config.StartupHook = ""
  997. }
  998. func TestPostDisconnectHook(t *testing.T) {
  999. Config.PostDisconnectHook = "http://127.0.0.1/"
  1000. remoteAddr := "127.0.0.1:80"
  1001. Config.checkPostDisconnectHook(remoteAddr, ProtocolHTTP, "", "", time.Now())
  1002. Config.checkPostDisconnectHook(remoteAddr, ProtocolSFTP, "", "", time.Now())
  1003. Config.PostDisconnectHook = "http://bar\x7f.com/"
  1004. Config.executePostDisconnectHook(remoteAddr, ProtocolSFTP, "", "", time.Now())
  1005. Config.PostDisconnectHook = fmt.Sprintf("http://%v", httpAddr)
  1006. Config.executePostDisconnectHook(remoteAddr, ProtocolSFTP, "", "", time.Now())
  1007. Config.PostDisconnectHook = "relativePath"
  1008. Config.executePostDisconnectHook(remoteAddr, ProtocolSFTP, "", "", time.Now())
  1009. if runtime.GOOS == osWindows {
  1010. Config.PostDisconnectHook = "C:\\a\\bad\\command"
  1011. Config.executePostDisconnectHook(remoteAddr, ProtocolSFTP, "", "", time.Now())
  1012. } else {
  1013. Config.PostDisconnectHook = "/invalid/path"
  1014. Config.executePostDisconnectHook(remoteAddr, ProtocolSFTP, "", "", time.Now())
  1015. hookCmd, err := exec.LookPath("true")
  1016. assert.NoError(t, err)
  1017. Config.PostDisconnectHook = hookCmd
  1018. Config.executePostDisconnectHook(remoteAddr, ProtocolSFTP, "", "", time.Now())
  1019. }
  1020. Config.PostDisconnectHook = ""
  1021. }
  1022. func TestPostConnectHook(t *testing.T) {
  1023. Config.PostConnectHook = ""
  1024. ipAddr := "127.0.0.1"
  1025. assert.NoError(t, Config.ExecutePostConnectHook(ipAddr, ProtocolFTP))
  1026. Config.PostConnectHook = "http://foo\x7f.com/"
  1027. assert.Error(t, Config.ExecutePostConnectHook(ipAddr, ProtocolSFTP))
  1028. Config.PostConnectHook = "http://invalid:1234/"
  1029. assert.Error(t, Config.ExecutePostConnectHook(ipAddr, ProtocolSFTP))
  1030. Config.PostConnectHook = fmt.Sprintf("http://%v/404", httpAddr)
  1031. assert.Error(t, Config.ExecutePostConnectHook(ipAddr, ProtocolFTP))
  1032. Config.PostConnectHook = fmt.Sprintf("http://%v", httpAddr)
  1033. assert.NoError(t, Config.ExecutePostConnectHook(ipAddr, ProtocolFTP))
  1034. Config.PostConnectHook = "invalid"
  1035. assert.Error(t, Config.ExecutePostConnectHook(ipAddr, ProtocolFTP))
  1036. if runtime.GOOS == osWindows {
  1037. Config.PostConnectHook = "C:\\bad\\command"
  1038. assert.Error(t, Config.ExecutePostConnectHook(ipAddr, ProtocolSFTP))
  1039. } else {
  1040. Config.PostConnectHook = "/invalid/path"
  1041. assert.Error(t, Config.ExecutePostConnectHook(ipAddr, ProtocolSFTP))
  1042. hookCmd, err := exec.LookPath("true")
  1043. assert.NoError(t, err)
  1044. Config.PostConnectHook = hookCmd
  1045. assert.NoError(t, Config.ExecutePostConnectHook(ipAddr, ProtocolSFTP))
  1046. }
  1047. Config.PostConnectHook = ""
  1048. }
  1049. func TestCryptoConvertFileInfo(t *testing.T) {
  1050. name := "name"
  1051. fs, err := vfs.NewCryptFs("connID1", os.TempDir(), "", vfs.CryptFsConfig{
  1052. Passphrase: kms.NewPlainSecret("secret"),
  1053. })
  1054. require.NoError(t, err)
  1055. cryptFs := fs.(*vfs.CryptFs)
  1056. info := vfs.NewFileInfo(name, true, 48, time.Now(), false)
  1057. assert.Equal(t, info, cryptFs.ConvertFileInfo(info))
  1058. info = vfs.NewFileInfo(name, false, 48, time.Now(), false)
  1059. assert.NotEqual(t, info.Size(), cryptFs.ConvertFileInfo(info).Size())
  1060. info = vfs.NewFileInfo(name, false, 33, time.Now(), false)
  1061. assert.Equal(t, int64(0), cryptFs.ConvertFileInfo(info).Size())
  1062. info = vfs.NewFileInfo(name, false, 1, time.Now(), false)
  1063. assert.Equal(t, int64(0), cryptFs.ConvertFileInfo(info).Size())
  1064. }
  1065. func TestFolderCopy(t *testing.T) {
  1066. folder := vfs.BaseVirtualFolder{
  1067. ID: 1,
  1068. Name: "name",
  1069. MappedPath: filepath.Clean(os.TempDir()),
  1070. UsedQuotaSize: 4096,
  1071. UsedQuotaFiles: 2,
  1072. LastQuotaUpdate: util.GetTimeAsMsSinceEpoch(time.Now()),
  1073. Users: []string{"user1", "user2"},
  1074. }
  1075. folderCopy := folder.GetACopy()
  1076. folder.ID = 2
  1077. folder.Users = []string{"user3"}
  1078. require.Len(t, folderCopy.Users, 2)
  1079. require.True(t, util.Contains(folderCopy.Users, "user1"))
  1080. require.True(t, util.Contains(folderCopy.Users, "user2"))
  1081. require.Equal(t, int64(1), folderCopy.ID)
  1082. require.Equal(t, folder.Name, folderCopy.Name)
  1083. require.Equal(t, folder.MappedPath, folderCopy.MappedPath)
  1084. require.Equal(t, folder.UsedQuotaSize, folderCopy.UsedQuotaSize)
  1085. require.Equal(t, folder.UsedQuotaFiles, folderCopy.UsedQuotaFiles)
  1086. require.Equal(t, folder.LastQuotaUpdate, folderCopy.LastQuotaUpdate)
  1087. folder.FsConfig = vfs.Filesystem{
  1088. CryptConfig: vfs.CryptFsConfig{
  1089. Passphrase: kms.NewPlainSecret("crypto secret"),
  1090. },
  1091. }
  1092. folderCopy = folder.GetACopy()
  1093. folder.FsConfig.CryptConfig.Passphrase = kms.NewEmptySecret()
  1094. require.Len(t, folderCopy.Users, 1)
  1095. require.True(t, util.Contains(folderCopy.Users, "user3"))
  1096. require.Equal(t, int64(2), folderCopy.ID)
  1097. require.Equal(t, folder.Name, folderCopy.Name)
  1098. require.Equal(t, folder.MappedPath, folderCopy.MappedPath)
  1099. require.Equal(t, folder.UsedQuotaSize, folderCopy.UsedQuotaSize)
  1100. require.Equal(t, folder.UsedQuotaFiles, folderCopy.UsedQuotaFiles)
  1101. require.Equal(t, folder.LastQuotaUpdate, folderCopy.LastQuotaUpdate)
  1102. require.Equal(t, "crypto secret", folderCopy.FsConfig.CryptConfig.Passphrase.GetPayload())
  1103. }
  1104. func TestCachedFs(t *testing.T) {
  1105. user := dataprovider.User{
  1106. BaseUser: sdk.BaseUser{
  1107. HomeDir: filepath.Clean(os.TempDir()),
  1108. },
  1109. }
  1110. conn := NewBaseConnection("id", ProtocolSFTP, "", "", user)
  1111. // changing the user should not affect the connection
  1112. user.HomeDir = filepath.Join(os.TempDir(), "temp")
  1113. err := os.Mkdir(user.HomeDir, os.ModePerm)
  1114. assert.NoError(t, err)
  1115. fs, err := user.GetFilesystem("")
  1116. assert.NoError(t, err)
  1117. p, err := fs.ResolvePath("/")
  1118. assert.NoError(t, err)
  1119. assert.Equal(t, user.GetHomeDir(), p)
  1120. _, p, err = conn.GetFsAndResolvedPath("/")
  1121. assert.NoError(t, err)
  1122. assert.Equal(t, filepath.Clean(os.TempDir()), p)
  1123. // the filesystem is cached changing the provider will not affect the connection
  1124. conn.User.FsConfig.Provider = sdk.S3FilesystemProvider
  1125. _, p, err = conn.GetFsAndResolvedPath("/")
  1126. assert.NoError(t, err)
  1127. assert.Equal(t, filepath.Clean(os.TempDir()), p)
  1128. user = dataprovider.User{}
  1129. user.HomeDir = filepath.Join(os.TempDir(), "temp")
  1130. user.FsConfig.Provider = sdk.S3FilesystemProvider
  1131. _, err = user.GetFilesystem("")
  1132. assert.Error(t, err)
  1133. err = os.Remove(user.HomeDir)
  1134. assert.NoError(t, err)
  1135. }
  1136. func TestParseAllowedIPAndRanges(t *testing.T) {
  1137. _, err := util.ParseAllowedIPAndRanges([]string{"1.1.1.1", "not an ip"})
  1138. assert.Error(t, err)
  1139. _, err = util.ParseAllowedIPAndRanges([]string{"1.1.1.5", "192.168.1.0/240"})
  1140. assert.Error(t, err)
  1141. allow, err := util.ParseAllowedIPAndRanges([]string{"192.168.1.2", "172.16.0.0/24"})
  1142. assert.NoError(t, err)
  1143. assert.True(t, allow[0](net.ParseIP("192.168.1.2")))
  1144. assert.False(t, allow[0](net.ParseIP("192.168.2.2")))
  1145. assert.True(t, allow[1](net.ParseIP("172.16.0.1")))
  1146. assert.False(t, allow[1](net.ParseIP("172.16.1.1")))
  1147. }
  1148. func TestHideConfidentialData(_ *testing.T) {
  1149. for _, provider := range []sdk.FilesystemProvider{sdk.LocalFilesystemProvider,
  1150. sdk.CryptedFilesystemProvider, sdk.S3FilesystemProvider, sdk.GCSFilesystemProvider,
  1151. sdk.AzureBlobFilesystemProvider, sdk.SFTPFilesystemProvider,
  1152. } {
  1153. u := dataprovider.User{
  1154. FsConfig: vfs.Filesystem{
  1155. Provider: provider,
  1156. },
  1157. }
  1158. u.PrepareForRendering()
  1159. f := vfs.BaseVirtualFolder{
  1160. FsConfig: vfs.Filesystem{
  1161. Provider: provider,
  1162. },
  1163. }
  1164. f.PrepareForRendering()
  1165. }
  1166. a := dataprovider.Admin{}
  1167. a.HideConfidentialData()
  1168. }
  1169. func TestUserPerms(t *testing.T) {
  1170. u := dataprovider.User{}
  1171. u.Permissions = make(map[string][]string)
  1172. u.Permissions["/"] = []string{dataprovider.PermUpload, dataprovider.PermDelete}
  1173. assert.True(t, u.HasAnyPerm([]string{dataprovider.PermRename, dataprovider.PermDelete}, "/"))
  1174. assert.False(t, u.HasAnyPerm([]string{dataprovider.PermRename, dataprovider.PermCreateDirs}, "/"))
  1175. u.Permissions["/"] = []string{dataprovider.PermDelete, dataprovider.PermCreateDirs}
  1176. assert.True(t, u.HasPermsDeleteAll("/"))
  1177. assert.False(t, u.HasPermsRenameAll("/"))
  1178. u.Permissions["/"] = []string{dataprovider.PermDeleteDirs, dataprovider.PermDeleteFiles, dataprovider.PermRenameDirs}
  1179. assert.True(t, u.HasPermsDeleteAll("/"))
  1180. assert.False(t, u.HasPermsRenameAll("/"))
  1181. u.Permissions["/"] = []string{dataprovider.PermDeleteDirs, dataprovider.PermRenameFiles, dataprovider.PermRenameDirs}
  1182. assert.False(t, u.HasPermsDeleteAll("/"))
  1183. assert.True(t, u.HasPermsRenameAll("/"))
  1184. }
  1185. func TestGetTLSVersion(t *testing.T) {
  1186. tlsVer := util.GetTLSVersion(0)
  1187. assert.Equal(t, uint16(tls.VersionTLS12), tlsVer)
  1188. tlsVer = util.GetTLSVersion(12)
  1189. assert.Equal(t, uint16(tls.VersionTLS12), tlsVer)
  1190. tlsVer = util.GetTLSVersion(2)
  1191. assert.Equal(t, uint16(tls.VersionTLS12), tlsVer)
  1192. tlsVer = util.GetTLSVersion(13)
  1193. assert.Equal(t, uint16(tls.VersionTLS13), tlsVer)
  1194. }
  1195. func TestCleanPath(t *testing.T) {
  1196. assert.Equal(t, "/", util.CleanPath("/"))
  1197. assert.Equal(t, "/", util.CleanPath("."))
  1198. assert.Equal(t, "/", util.CleanPath(""))
  1199. assert.Equal(t, "/", util.CleanPath("/."))
  1200. assert.Equal(t, "/", util.CleanPath("/a/.."))
  1201. assert.Equal(t, "/a", util.CleanPath("/a/"))
  1202. assert.Equal(t, "/a", util.CleanPath("a/"))
  1203. // filepath.ToSlash does not touch \ as char on unix systems
  1204. // so os.PathSeparator is used for windows compatible tests
  1205. bslash := string(os.PathSeparator)
  1206. assert.Equal(t, "/", util.CleanPath(bslash))
  1207. assert.Equal(t, "/", util.CleanPath(bslash+bslash))
  1208. assert.Equal(t, "/a", util.CleanPath(bslash+"a"+bslash))
  1209. assert.Equal(t, "/a", util.CleanPath("a"+bslash))
  1210. assert.Equal(t, "/a/b/c", util.CleanPath(bslash+"a"+bslash+bslash+"b"+bslash+bslash+"c"+bslash))
  1211. assert.Equal(t, "/C:/a", util.CleanPath("C:"+bslash+"a"))
  1212. }
  1213. func TestUserRecentActivity(t *testing.T) {
  1214. u := dataprovider.User{}
  1215. res := u.HasRecentActivity()
  1216. assert.False(t, res)
  1217. u.LastLogin = util.GetTimeAsMsSinceEpoch(time.Now())
  1218. res = u.HasRecentActivity()
  1219. assert.True(t, res)
  1220. u.LastLogin = util.GetTimeAsMsSinceEpoch(time.Now().Add(1 * time.Minute))
  1221. res = u.HasRecentActivity()
  1222. assert.False(t, res)
  1223. u.LastLogin = util.GetTimeAsMsSinceEpoch(time.Now().Add(1 * time.Second))
  1224. res = u.HasRecentActivity()
  1225. assert.True(t, res)
  1226. }
  1227. func TestVfsSameResource(t *testing.T) {
  1228. fs := vfs.Filesystem{}
  1229. other := vfs.Filesystem{}
  1230. res := fs.IsSameResource(other)
  1231. assert.True(t, res)
  1232. fs = vfs.Filesystem{
  1233. Provider: sdk.S3FilesystemProvider,
  1234. S3Config: vfs.S3FsConfig{
  1235. BaseS3FsConfig: sdk.BaseS3FsConfig{
  1236. Bucket: "a",
  1237. Region: "b",
  1238. },
  1239. },
  1240. }
  1241. other = vfs.Filesystem{
  1242. Provider: sdk.S3FilesystemProvider,
  1243. S3Config: vfs.S3FsConfig{
  1244. BaseS3FsConfig: sdk.BaseS3FsConfig{
  1245. Bucket: "a",
  1246. Region: "c",
  1247. },
  1248. },
  1249. }
  1250. res = fs.IsSameResource(other)
  1251. assert.False(t, res)
  1252. other = vfs.Filesystem{
  1253. Provider: sdk.S3FilesystemProvider,
  1254. S3Config: vfs.S3FsConfig{
  1255. BaseS3FsConfig: sdk.BaseS3FsConfig{
  1256. Bucket: "a",
  1257. Region: "b",
  1258. },
  1259. },
  1260. }
  1261. res = fs.IsSameResource(other)
  1262. assert.True(t, res)
  1263. fs = vfs.Filesystem{
  1264. Provider: sdk.GCSFilesystemProvider,
  1265. GCSConfig: vfs.GCSFsConfig{
  1266. BaseGCSFsConfig: sdk.BaseGCSFsConfig{
  1267. Bucket: "b",
  1268. },
  1269. },
  1270. }
  1271. other = vfs.Filesystem{
  1272. Provider: sdk.GCSFilesystemProvider,
  1273. GCSConfig: vfs.GCSFsConfig{
  1274. BaseGCSFsConfig: sdk.BaseGCSFsConfig{
  1275. Bucket: "c",
  1276. },
  1277. },
  1278. }
  1279. res = fs.IsSameResource(other)
  1280. assert.False(t, res)
  1281. other = vfs.Filesystem{
  1282. Provider: sdk.GCSFilesystemProvider,
  1283. GCSConfig: vfs.GCSFsConfig{
  1284. BaseGCSFsConfig: sdk.BaseGCSFsConfig{
  1285. Bucket: "b",
  1286. },
  1287. },
  1288. }
  1289. res = fs.IsSameResource(other)
  1290. assert.True(t, res)
  1291. sasURL := kms.NewPlainSecret("http://127.0.0.1/sasurl")
  1292. fs = vfs.Filesystem{
  1293. Provider: sdk.AzureBlobFilesystemProvider,
  1294. AzBlobConfig: vfs.AzBlobFsConfig{
  1295. BaseAzBlobFsConfig: sdk.BaseAzBlobFsConfig{
  1296. AccountName: "a",
  1297. },
  1298. SASURL: sasURL,
  1299. },
  1300. }
  1301. err := fs.Validate("data1")
  1302. assert.NoError(t, err)
  1303. other = vfs.Filesystem{
  1304. Provider: sdk.AzureBlobFilesystemProvider,
  1305. AzBlobConfig: vfs.AzBlobFsConfig{
  1306. BaseAzBlobFsConfig: sdk.BaseAzBlobFsConfig{
  1307. AccountName: "a",
  1308. },
  1309. SASURL: sasURL,
  1310. },
  1311. }
  1312. err = other.Validate("data2")
  1313. assert.NoError(t, err)
  1314. err = fs.AzBlobConfig.SASURL.TryDecrypt()
  1315. assert.NoError(t, err)
  1316. err = other.AzBlobConfig.SASURL.TryDecrypt()
  1317. assert.NoError(t, err)
  1318. res = fs.IsSameResource(other)
  1319. assert.True(t, res)
  1320. fs.AzBlobConfig.AccountName = "b"
  1321. res = fs.IsSameResource(other)
  1322. assert.False(t, res)
  1323. fs.AzBlobConfig.AccountName = "a"
  1324. other.AzBlobConfig.SASURL = kms.NewPlainSecret("http://127.1.1.1/sasurl")
  1325. err = other.Validate("data2")
  1326. assert.NoError(t, err)
  1327. err = other.AzBlobConfig.SASURL.TryDecrypt()
  1328. assert.NoError(t, err)
  1329. res = fs.IsSameResource(other)
  1330. assert.False(t, res)
  1331. fs = vfs.Filesystem{
  1332. Provider: sdk.HTTPFilesystemProvider,
  1333. HTTPConfig: vfs.HTTPFsConfig{
  1334. BaseHTTPFsConfig: sdk.BaseHTTPFsConfig{
  1335. Endpoint: "http://127.0.0.1/httpfs",
  1336. Username: "a",
  1337. },
  1338. },
  1339. }
  1340. other = vfs.Filesystem{
  1341. Provider: sdk.HTTPFilesystemProvider,
  1342. HTTPConfig: vfs.HTTPFsConfig{
  1343. BaseHTTPFsConfig: sdk.BaseHTTPFsConfig{
  1344. Endpoint: "http://127.0.0.1/httpfs",
  1345. Username: "b",
  1346. },
  1347. },
  1348. }
  1349. res = fs.IsSameResource(other)
  1350. assert.True(t, res)
  1351. fs.HTTPConfig.EqualityCheckMode = 1
  1352. res = fs.IsSameResource(other)
  1353. assert.False(t, res)
  1354. }
  1355. func TestUpdateTransferTimestamps(t *testing.T) {
  1356. username := "user_test_timestamps"
  1357. user := &dataprovider.User{
  1358. BaseUser: sdk.BaseUser{
  1359. Username: username,
  1360. HomeDir: filepath.Join(os.TempDir(), username),
  1361. Status: 1,
  1362. Permissions: map[string][]string{
  1363. "/": {dataprovider.PermAny},
  1364. },
  1365. },
  1366. }
  1367. err := dataprovider.AddUser(user, "", "", "")
  1368. assert.NoError(t, err)
  1369. assert.Equal(t, int64(0), user.FirstUpload)
  1370. assert.Equal(t, int64(0), user.FirstDownload)
  1371. err = dataprovider.UpdateUserTransferTimestamps(username, true)
  1372. assert.NoError(t, err)
  1373. userGet, err := dataprovider.UserExists(username, "")
  1374. assert.NoError(t, err)
  1375. assert.Greater(t, userGet.FirstUpload, int64(0))
  1376. assert.Equal(t, int64(0), user.FirstDownload)
  1377. err = dataprovider.UpdateUserTransferTimestamps(username, false)
  1378. assert.NoError(t, err)
  1379. userGet, err = dataprovider.UserExists(username, "")
  1380. assert.NoError(t, err)
  1381. assert.Greater(t, userGet.FirstUpload, int64(0))
  1382. assert.Greater(t, userGet.FirstDownload, int64(0))
  1383. // updating again must fail
  1384. err = dataprovider.UpdateUserTransferTimestamps(username, true)
  1385. assert.Error(t, err)
  1386. err = dataprovider.UpdateUserTransferTimestamps(username, false)
  1387. assert.Error(t, err)
  1388. // cleanup
  1389. err = dataprovider.DeleteUser(username, "", "", "")
  1390. assert.NoError(t, err)
  1391. }
  1392. func TestIPList(t *testing.T) {
  1393. type test struct {
  1394. ip string
  1395. protocol string
  1396. expectedMatch bool
  1397. expectedMode int
  1398. expectedErr bool
  1399. }
  1400. entries := []dataprovider.IPListEntry{
  1401. {
  1402. IPOrNet: "192.168.0.0/25",
  1403. Type: dataprovider.IPListTypeDefender,
  1404. Mode: dataprovider.ListModeAllow,
  1405. },
  1406. {
  1407. IPOrNet: "192.168.0.128/25",
  1408. Type: dataprovider.IPListTypeDefender,
  1409. Mode: dataprovider.ListModeDeny,
  1410. Protocols: 3,
  1411. },
  1412. {
  1413. IPOrNet: "192.168.2.128/32",
  1414. Type: dataprovider.IPListTypeDefender,
  1415. Mode: dataprovider.ListModeAllow,
  1416. Protocols: 5,
  1417. },
  1418. {
  1419. IPOrNet: "::/0",
  1420. Type: dataprovider.IPListTypeDefender,
  1421. Mode: dataprovider.ListModeDeny,
  1422. Protocols: 4,
  1423. },
  1424. {
  1425. IPOrNet: "2001:4860:4860::8888/120",
  1426. Type: dataprovider.IPListTypeDefender,
  1427. Mode: dataprovider.ListModeDeny,
  1428. Protocols: 1,
  1429. },
  1430. {
  1431. IPOrNet: "2001:4860:4860::8988/120",
  1432. Type: dataprovider.IPListTypeDefender,
  1433. Mode: dataprovider.ListModeAllow,
  1434. Protocols: 3,
  1435. },
  1436. {
  1437. IPOrNet: "::1/128",
  1438. Type: dataprovider.IPListTypeDefender,
  1439. Mode: dataprovider.ListModeAllow,
  1440. Protocols: 0,
  1441. },
  1442. }
  1443. ipList, err := dataprovider.NewIPList(dataprovider.IPListTypeDefender)
  1444. require.NoError(t, err)
  1445. for idx := range entries {
  1446. e := entries[idx]
  1447. err := dataprovider.AddIPListEntry(&e, "", "", "")
  1448. assert.NoError(t, err)
  1449. }
  1450. tests := []test{
  1451. {ip: "1.1.1.1", protocol: ProtocolSSH, expectedMatch: false, expectedMode: 0, expectedErr: false},
  1452. {ip: "invalid ip", protocol: ProtocolSSH, expectedMatch: false, expectedMode: 0, expectedErr: true},
  1453. {ip: "192.168.0.1", protocol: ProtocolFTP, expectedMatch: true, expectedMode: dataprovider.ListModeAllow, expectedErr: false},
  1454. {ip: "192.168.0.2", protocol: ProtocolHTTP, expectedMatch: true, expectedMode: dataprovider.ListModeAllow, expectedErr: false},
  1455. {ip: "192.168.0.3", protocol: ProtocolWebDAV, expectedMatch: true, expectedMode: dataprovider.ListModeAllow, expectedErr: false},
  1456. {ip: "192.168.0.4", protocol: ProtocolSSH, expectedMatch: true, expectedMode: dataprovider.ListModeAllow, expectedErr: false},
  1457. {ip: "192.168.0.156", protocol: ProtocolSSH, expectedMatch: true, expectedMode: dataprovider.ListModeDeny, expectedErr: false},
  1458. {ip: "192.168.0.158", protocol: ProtocolFTP, expectedMatch: true, expectedMode: dataprovider.ListModeDeny, expectedErr: false},
  1459. {ip: "192.168.0.158", protocol: ProtocolHTTP, expectedMatch: false, expectedMode: 0, expectedErr: false},
  1460. {ip: "192.168.2.128", protocol: ProtocolHTTP, expectedMatch: false, expectedMode: 0, expectedErr: false},
  1461. {ip: "192.168.2.128", protocol: ProtocolSSH, expectedMatch: true, expectedMode: dataprovider.ListModeAllow, expectedErr: false},
  1462. {ip: "::2", protocol: ProtocolSSH, expectedMatch: false, expectedMode: 0, expectedErr: false},
  1463. {ip: "::2", protocol: ProtocolWebDAV, expectedMatch: true, expectedMode: dataprovider.ListModeDeny, expectedErr: false},
  1464. {ip: "::1", protocol: ProtocolSSH, expectedMatch: true, expectedMode: dataprovider.ListModeAllow, expectedErr: false},
  1465. {ip: "::1", protocol: ProtocolHTTP, expectedMatch: true, expectedMode: dataprovider.ListModeAllow, expectedErr: false},
  1466. {ip: "2001:4860:4860:0000:0000:0000:0000:8889", protocol: ProtocolSSH, expectedMatch: true, expectedMode: dataprovider.ListModeDeny, expectedErr: false},
  1467. {ip: "2001:4860:4860:0000:0000:0000:0000:8889", protocol: ProtocolFTP, expectedMatch: false, expectedMode: 0, expectedErr: false},
  1468. {ip: "2001:4860:4860:0000:0000:0000:0000:8989", protocol: ProtocolFTP, expectedMatch: true, expectedMode: dataprovider.ListModeAllow, expectedErr: false},
  1469. {ip: "2001:4860:4860:0000:0000:0000:0000:89F1", protocol: ProtocolSSH, expectedMatch: true, expectedMode: dataprovider.ListModeAllow, expectedErr: false},
  1470. {ip: "2001:4860:4860:0000:0000:0000:0000:89F1", protocol: ProtocolHTTP, expectedMatch: false, expectedMode: 0, expectedErr: false},
  1471. }
  1472. for _, tc := range tests {
  1473. match, mode, err := ipList.IsListed(tc.ip, tc.protocol)
  1474. if tc.expectedErr {
  1475. assert.Error(t, err, "ip %s, protocol %s", tc.ip, tc.protocol)
  1476. } else {
  1477. assert.NoError(t, err, "ip %s, protocol %s", tc.ip, tc.protocol)
  1478. }
  1479. assert.Equal(t, tc.expectedMatch, match, "ip %s, protocol %s", tc.ip, tc.protocol)
  1480. assert.Equal(t, tc.expectedMode, mode, "ip %s, protocol %s", tc.ip, tc.protocol)
  1481. }
  1482. ipList.DisableMemoryMode()
  1483. for _, tc := range tests {
  1484. match, mode, err := ipList.IsListed(tc.ip, tc.protocol)
  1485. if tc.expectedErr {
  1486. assert.Error(t, err, "ip %s, protocol %s", tc.ip, tc.protocol)
  1487. } else {
  1488. assert.NoError(t, err, "ip %s, protocol %s", tc.ip, tc.protocol)
  1489. }
  1490. assert.Equal(t, tc.expectedMatch, match, "ip %s, protocol %s", tc.ip, tc.protocol)
  1491. assert.Equal(t, tc.expectedMode, mode, "ip %s, protocol %s", tc.ip, tc.protocol)
  1492. }
  1493. for _, e := range entries {
  1494. err := dataprovider.DeleteIPListEntry(e.IPOrNet, e.Type, "", "", "")
  1495. assert.NoError(t, err)
  1496. }
  1497. }
  1498. func TestSQLPlaceholderLimits(t *testing.T) {
  1499. numGroups := 120
  1500. numUsers := 120
  1501. var groupMapping []sdk.GroupMapping
  1502. folder := vfs.BaseVirtualFolder{
  1503. Name: "testfolder",
  1504. MappedPath: filepath.Join(os.TempDir(), "folder"),
  1505. }
  1506. err := dataprovider.AddFolder(&folder, "", "", "")
  1507. assert.NoError(t, err)
  1508. for i := 0; i < numGroups; i++ {
  1509. group := dataprovider.Group{
  1510. BaseGroup: sdk.BaseGroup{
  1511. Name: fmt.Sprintf("testgroup%d", i),
  1512. },
  1513. UserSettings: dataprovider.GroupUserSettings{
  1514. BaseGroupUserSettings: sdk.BaseGroupUserSettings{
  1515. Permissions: map[string][]string{
  1516. fmt.Sprintf("/dir%d", i): {dataprovider.PermAny},
  1517. },
  1518. },
  1519. },
  1520. }
  1521. group.VirtualFolders = append(group.VirtualFolders, vfs.VirtualFolder{
  1522. BaseVirtualFolder: folder,
  1523. VirtualPath: "/vdir",
  1524. })
  1525. err := dataprovider.AddGroup(&group, "", "", "")
  1526. assert.NoError(t, err)
  1527. groupMapping = append(groupMapping, sdk.GroupMapping{
  1528. Name: group.Name,
  1529. Type: sdk.GroupTypeSecondary,
  1530. })
  1531. }
  1532. user := dataprovider.User{
  1533. BaseUser: sdk.BaseUser{
  1534. Username: "testusername",
  1535. HomeDir: filepath.Join(os.TempDir(), "testhome"),
  1536. Status: 1,
  1537. Permissions: map[string][]string{
  1538. "/": {dataprovider.PermAny},
  1539. },
  1540. },
  1541. Groups: groupMapping,
  1542. }
  1543. err = dataprovider.AddUser(&user, "", "", "")
  1544. assert.NoError(t, err)
  1545. users, err := dataprovider.GetUsersForQuotaCheck(map[string]bool{user.Username: true})
  1546. assert.NoError(t, err)
  1547. if assert.Len(t, users, 1) {
  1548. for i := 0; i < numGroups; i++ {
  1549. _, ok := users[0].Permissions[fmt.Sprintf("/dir%d", i)]
  1550. assert.True(t, ok)
  1551. }
  1552. }
  1553. err = dataprovider.DeleteUser(user.Username, "", "", "")
  1554. assert.NoError(t, err)
  1555. for i := 0; i < numUsers; i++ {
  1556. user := dataprovider.User{
  1557. BaseUser: sdk.BaseUser{
  1558. Username: fmt.Sprintf("testusername%d", i),
  1559. HomeDir: filepath.Join(os.TempDir()),
  1560. Status: 1,
  1561. Permissions: map[string][]string{
  1562. "/": {dataprovider.PermAny},
  1563. },
  1564. },
  1565. Groups: []sdk.GroupMapping{
  1566. {
  1567. Name: "testgroup0",
  1568. Type: sdk.GroupTypePrimary,
  1569. },
  1570. },
  1571. }
  1572. err := dataprovider.AddUser(&user, "", "", "")
  1573. assert.NoError(t, err)
  1574. }
  1575. time.Sleep(100 * time.Millisecond)
  1576. err = dataprovider.DeleteFolder(folder.Name, "", "", "")
  1577. assert.NoError(t, err)
  1578. for i := 0; i < numUsers; i++ {
  1579. username := fmt.Sprintf("testusername%d", i)
  1580. user, err := dataprovider.UserExists(username, "")
  1581. assert.NoError(t, err)
  1582. assert.Greater(t, user.UpdatedAt, user.CreatedAt)
  1583. err = dataprovider.DeleteUser(username, "", "", "")
  1584. assert.NoError(t, err)
  1585. }
  1586. for i := 0; i < numGroups; i++ {
  1587. groupName := fmt.Sprintf("testgroup%d", i)
  1588. err = dataprovider.DeleteGroup(groupName, "", "", "")
  1589. assert.NoError(t, err)
  1590. }
  1591. }
  1592. func TestALPNProtocols(t *testing.T) {
  1593. protocols := util.GetALPNProtocols(nil)
  1594. assert.Equal(t, []string{"http/1.1", "h2"}, protocols)
  1595. protocols = util.GetALPNProtocols([]string{"invalid1", "invalid2"})
  1596. assert.Equal(t, []string{"http/1.1", "h2"}, protocols)
  1597. protocols = util.GetALPNProtocols([]string{"invalid1", "h2", "invalid2"})
  1598. assert.Equal(t, []string{"h2"}, protocols)
  1599. protocols = util.GetALPNProtocols([]string{"h2", "http/1.1"})
  1600. assert.Equal(t, []string{"h2", "http/1.1"}, protocols)
  1601. }
  1602. func BenchmarkBcryptHashing(b *testing.B) {
  1603. bcryptPassword := "bcryptpassword"
  1604. for i := 0; i < b.N; i++ {
  1605. _, err := bcrypt.GenerateFromPassword([]byte(bcryptPassword), 10)
  1606. if err != nil {
  1607. panic(err)
  1608. }
  1609. }
  1610. }
  1611. func BenchmarkCompareBcryptPassword(b *testing.B) {
  1612. bcryptPassword := "$2a$10$lPDdnDimJZ7d5/GwL6xDuOqoZVRXok6OHHhivCnanWUtcgN0Zafki"
  1613. for i := 0; i < b.N; i++ {
  1614. err := bcrypt.CompareHashAndPassword([]byte(bcryptPassword), []byte("password"))
  1615. if err != nil {
  1616. panic(err)
  1617. }
  1618. }
  1619. }
  1620. func BenchmarkArgon2Hashing(b *testing.B) {
  1621. argonPassword := "argon2password"
  1622. for i := 0; i < b.N; i++ {
  1623. _, err := argon2id.CreateHash(argonPassword, argon2id.DefaultParams)
  1624. if err != nil {
  1625. panic(err)
  1626. }
  1627. }
  1628. }
  1629. func BenchmarkCompareArgon2Password(b *testing.B) {
  1630. argon2Password := "$argon2id$v=19$m=65536,t=1,p=2$aOoAOdAwvzhOgi7wUFjXlw$wn/y37dBWdKHtPXHR03nNaKHWKPXyNuVXOknaU+YZ+s"
  1631. for i := 0; i < b.N; i++ {
  1632. _, err := argon2id.ComparePasswordAndHash("password", argon2Password)
  1633. if err != nil {
  1634. panic(err)
  1635. }
  1636. }
  1637. }
  1638. func BenchmarkAddRemoveConnections(b *testing.B) {
  1639. var conns []ActiveConnection
  1640. for i := 0; i < 100; i++ {
  1641. conns = append(conns, &fakeConnection{
  1642. BaseConnection: NewBaseConnection(fmt.Sprintf("id%d", i), ProtocolSFTP, "", "", dataprovider.User{
  1643. BaseUser: sdk.BaseUser{
  1644. Username: userTestUsername,
  1645. },
  1646. }),
  1647. })
  1648. }
  1649. b.ResetTimer()
  1650. for i := 0; i < b.N; i++ {
  1651. for _, c := range conns {
  1652. if err := Connections.Add(c); err != nil {
  1653. panic(err)
  1654. }
  1655. }
  1656. var wg sync.WaitGroup
  1657. for idx := len(conns) - 1; idx >= 0; idx-- {
  1658. wg.Add(1)
  1659. go func(index int) {
  1660. defer wg.Done()
  1661. Connections.Remove(conns[index].GetID())
  1662. }(idx)
  1663. }
  1664. wg.Wait()
  1665. }
  1666. }
  1667. func BenchmarkAddRemoveSSHConnections(b *testing.B) {
  1668. conn1, conn2 := net.Pipe()
  1669. var conns []*SSHConnection
  1670. for i := 0; i < 2000; i++ {
  1671. conns = append(conns, NewSSHConnection(fmt.Sprintf("id%d", i), conn1))
  1672. }
  1673. b.ResetTimer()
  1674. for i := 0; i < b.N; i++ {
  1675. for _, c := range conns {
  1676. Connections.AddSSHConnection(c)
  1677. }
  1678. for idx := len(conns) - 1; idx >= 0; idx-- {
  1679. Connections.RemoveSSHConnection(conns[idx].GetID())
  1680. }
  1681. }
  1682. conn1.Close()
  1683. conn2.Close()
  1684. }