ctl_v3_auth_test.go 30 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075
  1. // Copyright 2016 The etcd Authors
  2. //
  3. // Licensed under the Apache License, Version 2.0 (the "License");
  4. // you may not use this file except in compliance with the License.
  5. // You may obtain a copy of the License at
  6. //
  7. // http://www.apache.org/licenses/LICENSE-2.0
  8. //
  9. // Unless required by applicable law or agreed to in writing, software
  10. // distributed under the License is distributed on an "AS IS" BASIS,
  11. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. // See the License for the specific language governing permissions and
  13. // limitations under the License.
  14. package e2e
  15. import (
  16. "fmt"
  17. "os"
  18. "testing"
  19. "github.com/coreos/etcd/clientv3"
  20. )
  21. func TestCtlV3AuthEnable(t *testing.T) { testCtl(t, authEnableTest) }
  22. func TestCtlV3AuthDisable(t *testing.T) { testCtl(t, authDisableTest) }
  23. func TestCtlV3AuthWriteKey(t *testing.T) { testCtl(t, authCredWriteKeyTest) }
  24. func TestCtlV3AuthRoleUpdate(t *testing.T) { testCtl(t, authRoleUpdateTest) }
  25. func TestCtlV3AuthUserDeleteDuringOps(t *testing.T) { testCtl(t, authUserDeleteDuringOpsTest) }
  26. func TestCtlV3AuthRoleRevokeDuringOps(t *testing.T) { testCtl(t, authRoleRevokeDuringOpsTest) }
  27. func TestCtlV3AuthTxn(t *testing.T) { testCtl(t, authTestTxn) }
  28. func TestCtlV3AuthPrefixPerm(t *testing.T) { testCtl(t, authTestPrefixPerm) }
  29. func TestCtlV3AuthMemberAdd(t *testing.T) { testCtl(t, authTestMemberAdd) }
  30. func TestCtlV3AuthMemberRemove(t *testing.T) {
  31. testCtl(t, authTestMemberRemove, withQuorum(), withNoStrictReconfig())
  32. }
  33. func TestCtlV3AuthMemberUpdate(t *testing.T) { testCtl(t, authTestMemberUpdate) }
  34. func TestCtlV3AuthCertCN(t *testing.T) { testCtl(t, authTestCertCN, withCfg(configClientTLSCertAuth)) }
  35. func TestCtlV3AuthRevokeWithDelete(t *testing.T) { testCtl(t, authTestRevokeWithDelete) }
  36. func TestCtlV3AuthInvalidMgmt(t *testing.T) { testCtl(t, authTestInvalidMgmt) }
  37. func TestCtlV3AuthFromKeyPerm(t *testing.T) { testCtl(t, authTestFromKeyPerm) }
  38. func TestCtlV3AuthAndWatch(t *testing.T) { testCtl(t, authTestWatch) }
  39. func TestCtlV3AuthLeaseTestKeepAlive(t *testing.T) { testCtl(t, authLeaseTestKeepAlive) }
  40. func TestCtlV3AuthLeaseTestTimeToLiveExpired(t *testing.T) { testCtl(t, authLeaseTestTimeToLiveExpired) }
  41. func TestCtlV3AuthLeaseGrantLeases(t *testing.T) { testCtl(t, authLeaseTestLeaseGrantLeases) }
  42. func TestCtlV3AuthLeaseRevoke(t *testing.T) { testCtl(t, authLeaseTestLeaseRevoke) }
  43. func TestCtlV3AuthRoleGet(t *testing.T) { testCtl(t, authTestRoleGet) }
  44. func TestCtlV3AuthUserGet(t *testing.T) { testCtl(t, authTestUserGet) }
  45. func TestCtlV3AuthRoleList(t *testing.T) { testCtl(t, authTestRoleList) }
  46. func TestCtlV3AuthDefrag(t *testing.T) { testCtl(t, authTestDefrag) }
  47. func TestCtlV3AuthEndpointHealth(t *testing.T) {
  48. testCtl(t, authTestEndpointHealth, withQuorum())
  49. }
  50. func TestCtlV3AuthSnapshot(t *testing.T) { testCtl(t, authTestSnapshot) }
  51. func TestCtlV3AuthCertCNAndUsername(t *testing.T) {
  52. testCtl(t, authTestCertCNAndUsername, withCfg(configClientTLSCertAuth))
  53. }
  54. func authEnableTest(cx ctlCtx) {
  55. if err := authEnable(cx); err != nil {
  56. cx.t.Fatal(err)
  57. }
  58. }
  59. func authEnable(cx ctlCtx) error {
  60. // create root user with root role
  61. if err := ctlV3User(cx, []string{"add", "root", "--interactive=false"}, "User root created", []string{"root"}); err != nil {
  62. return fmt.Errorf("failed to create root user %v", err)
  63. }
  64. if err := ctlV3User(cx, []string{"grant-role", "root", "root"}, "Role root is granted to user root", nil); err != nil {
  65. return fmt.Errorf("failed to grant root user root role %v", err)
  66. }
  67. if err := ctlV3AuthEnable(cx); err != nil {
  68. return fmt.Errorf("authEnableTest ctlV3AuthEnable error (%v)", err)
  69. }
  70. return nil
  71. }
  72. func ctlV3AuthEnable(cx ctlCtx) error {
  73. cmdArgs := append(cx.PrefixArgs(), "auth", "enable")
  74. return spawnWithExpect(cmdArgs, "Authentication Enabled")
  75. }
  76. func authDisableTest(cx ctlCtx) {
  77. // a key that isn't granted to test-user
  78. if err := ctlV3Put(cx, "hoo", "a", ""); err != nil {
  79. cx.t.Fatal(err)
  80. }
  81. if err := authEnable(cx); err != nil {
  82. cx.t.Fatal(err)
  83. }
  84. cx.user, cx.pass = "root", "root"
  85. authSetupTestUser(cx)
  86. // test-user doesn't have the permission, it must fail
  87. cx.user, cx.pass = "test-user", "pass"
  88. if err := ctlV3PutFailPerm(cx, "hoo", "bar"); err != nil {
  89. cx.t.Fatal(err)
  90. }
  91. cx.user, cx.pass = "root", "root"
  92. if err := ctlV3AuthDisable(cx); err != nil {
  93. cx.t.Fatalf("authDisableTest ctlV3AuthDisable error (%v)", err)
  94. }
  95. // now ErrAuthNotEnabled of Authenticate() is simply ignored
  96. cx.user, cx.pass = "test-user", "pass"
  97. if err := ctlV3Put(cx, "hoo", "bar", ""); err != nil {
  98. cx.t.Fatal(err)
  99. }
  100. // now the key can be accessed
  101. cx.user, cx.pass = "", ""
  102. if err := ctlV3Put(cx, "hoo", "bar", ""); err != nil {
  103. cx.t.Fatal(err)
  104. }
  105. // confirm put succeeded
  106. if err := ctlV3Get(cx, []string{"hoo"}, []kv{{"hoo", "bar"}}...); err != nil {
  107. cx.t.Fatal(err)
  108. }
  109. }
  110. func ctlV3AuthDisable(cx ctlCtx) error {
  111. cmdArgs := append(cx.PrefixArgs(), "auth", "disable")
  112. return spawnWithExpect(cmdArgs, "Authentication Disabled")
  113. }
  114. func authCredWriteKeyTest(cx ctlCtx) {
  115. // baseline key to check for failed puts
  116. if err := ctlV3Put(cx, "foo", "a", ""); err != nil {
  117. cx.t.Fatal(err)
  118. }
  119. if err := authEnable(cx); err != nil {
  120. cx.t.Fatal(err)
  121. }
  122. cx.user, cx.pass = "root", "root"
  123. authSetupTestUser(cx)
  124. // confirm root role can access to all keys
  125. if err := ctlV3Put(cx, "foo", "bar", ""); err != nil {
  126. cx.t.Fatal(err)
  127. }
  128. if err := ctlV3Get(cx, []string{"foo"}, []kv{{"foo", "bar"}}...); err != nil {
  129. cx.t.Fatal(err)
  130. }
  131. // try invalid user
  132. cx.user, cx.pass = "a", "b"
  133. if err := ctlV3PutFailAuth(cx, "foo", "bar"); err != nil {
  134. cx.t.Fatal(err)
  135. }
  136. // confirm put failed
  137. cx.user, cx.pass = "test-user", "pass"
  138. if err := ctlV3Get(cx, []string{"foo"}, []kv{{"foo", "bar"}}...); err != nil {
  139. cx.t.Fatal(err)
  140. }
  141. // try good user
  142. cx.user, cx.pass = "test-user", "pass"
  143. if err := ctlV3Put(cx, "foo", "bar2", ""); err != nil {
  144. cx.t.Fatal(err)
  145. }
  146. // confirm put succeeded
  147. if err := ctlV3Get(cx, []string{"foo"}, []kv{{"foo", "bar2"}}...); err != nil {
  148. cx.t.Fatal(err)
  149. }
  150. // try bad password
  151. cx.user, cx.pass = "test-user", "badpass"
  152. if err := ctlV3PutFailAuth(cx, "foo", "baz"); err != nil {
  153. cx.t.Fatal(err)
  154. }
  155. // confirm put failed
  156. cx.user, cx.pass = "test-user", "pass"
  157. if err := ctlV3Get(cx, []string{"foo"}, []kv{{"foo", "bar2"}}...); err != nil {
  158. cx.t.Fatal(err)
  159. }
  160. }
  161. func authRoleUpdateTest(cx ctlCtx) {
  162. if err := ctlV3Put(cx, "foo", "bar", ""); err != nil {
  163. cx.t.Fatal(err)
  164. }
  165. if err := authEnable(cx); err != nil {
  166. cx.t.Fatal(err)
  167. }
  168. cx.user, cx.pass = "root", "root"
  169. authSetupTestUser(cx)
  170. // try put to not granted key
  171. cx.user, cx.pass = "test-user", "pass"
  172. if err := ctlV3PutFailPerm(cx, "hoo", "bar"); err != nil {
  173. cx.t.Fatal(err)
  174. }
  175. // grant a new key
  176. cx.user, cx.pass = "root", "root"
  177. if err := ctlV3RoleGrantPermission(cx, "test-role", grantingPerm{true, true, "hoo", "", false}); err != nil {
  178. cx.t.Fatal(err)
  179. }
  180. // try a newly granted key
  181. cx.user, cx.pass = "test-user", "pass"
  182. if err := ctlV3Put(cx, "hoo", "bar", ""); err != nil {
  183. cx.t.Fatal(err)
  184. }
  185. // confirm put succeeded
  186. if err := ctlV3Get(cx, []string{"hoo"}, []kv{{"hoo", "bar"}}...); err != nil {
  187. cx.t.Fatal(err)
  188. }
  189. // revoke the newly granted key
  190. cx.user, cx.pass = "root", "root"
  191. if err := ctlV3RoleRevokePermission(cx, "test-role", "hoo", "", false); err != nil {
  192. cx.t.Fatal(err)
  193. }
  194. // try put to the revoked key
  195. cx.user, cx.pass = "test-user", "pass"
  196. if err := ctlV3PutFailPerm(cx, "hoo", "bar"); err != nil {
  197. cx.t.Fatal(err)
  198. }
  199. // confirm a key still granted can be accessed
  200. if err := ctlV3Get(cx, []string{"foo"}, []kv{{"foo", "bar"}}...); err != nil {
  201. cx.t.Fatal(err)
  202. }
  203. }
  204. func authUserDeleteDuringOpsTest(cx ctlCtx) {
  205. if err := ctlV3Put(cx, "foo", "bar", ""); err != nil {
  206. cx.t.Fatal(err)
  207. }
  208. if err := authEnable(cx); err != nil {
  209. cx.t.Fatal(err)
  210. }
  211. cx.user, cx.pass = "root", "root"
  212. authSetupTestUser(cx)
  213. // create a key
  214. cx.user, cx.pass = "test-user", "pass"
  215. if err := ctlV3Put(cx, "foo", "bar", ""); err != nil {
  216. cx.t.Fatal(err)
  217. }
  218. // confirm put succeeded
  219. if err := ctlV3Get(cx, []string{"foo"}, []kv{{"foo", "bar"}}...); err != nil {
  220. cx.t.Fatal(err)
  221. }
  222. // delete the user
  223. cx.user, cx.pass = "root", "root"
  224. err := ctlV3User(cx, []string{"delete", "test-user"}, "User test-user deleted", []string{})
  225. if err != nil {
  226. cx.t.Fatal(err)
  227. }
  228. // check the user is deleted
  229. cx.user, cx.pass = "test-user", "pass"
  230. if err := ctlV3PutFailAuth(cx, "foo", "baz"); err != nil {
  231. cx.t.Fatal(err)
  232. }
  233. }
  234. func authRoleRevokeDuringOpsTest(cx ctlCtx) {
  235. if err := ctlV3Put(cx, "foo", "bar", ""); err != nil {
  236. cx.t.Fatal(err)
  237. }
  238. if err := authEnable(cx); err != nil {
  239. cx.t.Fatal(err)
  240. }
  241. cx.user, cx.pass = "root", "root"
  242. authSetupTestUser(cx)
  243. // create a key
  244. cx.user, cx.pass = "test-user", "pass"
  245. if err := ctlV3Put(cx, "foo", "bar", ""); err != nil {
  246. cx.t.Fatal(err)
  247. }
  248. // confirm put succeeded
  249. if err := ctlV3Get(cx, []string{"foo"}, []kv{{"foo", "bar"}}...); err != nil {
  250. cx.t.Fatal(err)
  251. }
  252. // create a new role
  253. cx.user, cx.pass = "root", "root"
  254. if err := ctlV3Role(cx, []string{"add", "test-role2"}, "Role test-role2 created"); err != nil {
  255. cx.t.Fatal(err)
  256. }
  257. // grant a new key to the new role
  258. if err := ctlV3RoleGrantPermission(cx, "test-role2", grantingPerm{true, true, "hoo", "", false}); err != nil {
  259. cx.t.Fatal(err)
  260. }
  261. // grant the new role to the user
  262. if err := ctlV3User(cx, []string{"grant-role", "test-user", "test-role2"}, "Role test-role2 is granted to user test-user", nil); err != nil {
  263. cx.t.Fatal(err)
  264. }
  265. // try a newly granted key
  266. cx.user, cx.pass = "test-user", "pass"
  267. if err := ctlV3Put(cx, "hoo", "bar", ""); err != nil {
  268. cx.t.Fatal(err)
  269. }
  270. // confirm put succeeded
  271. if err := ctlV3Get(cx, []string{"hoo"}, []kv{{"hoo", "bar"}}...); err != nil {
  272. cx.t.Fatal(err)
  273. }
  274. // revoke a role from the user
  275. cx.user, cx.pass = "root", "root"
  276. err := ctlV3User(cx, []string{"revoke-role", "test-user", "test-role"}, "Role test-role is revoked from user test-user", []string{})
  277. if err != nil {
  278. cx.t.Fatal(err)
  279. }
  280. // check the role is revoked and permission is lost from the user
  281. cx.user, cx.pass = "test-user", "pass"
  282. if err := ctlV3PutFailPerm(cx, "foo", "baz"); err != nil {
  283. cx.t.Fatal(err)
  284. }
  285. // try a key that can be accessed from the remaining role
  286. cx.user, cx.pass = "test-user", "pass"
  287. if err := ctlV3Put(cx, "hoo", "bar2", ""); err != nil {
  288. cx.t.Fatal(err)
  289. }
  290. // confirm put succeeded
  291. if err := ctlV3Get(cx, []string{"hoo"}, []kv{{"hoo", "bar2"}}...); err != nil {
  292. cx.t.Fatal(err)
  293. }
  294. }
  295. func ctlV3PutFailAuth(cx ctlCtx, key, val string) error {
  296. return spawnWithExpect(append(cx.PrefixArgs(), "put", key, val), "authentication failed")
  297. }
  298. func ctlV3PutFailPerm(cx ctlCtx, key, val string) error {
  299. return spawnWithExpect(append(cx.PrefixArgs(), "put", key, val), "permission denied")
  300. }
  301. func authSetupTestUser(cx ctlCtx) {
  302. if err := ctlV3User(cx, []string{"add", "test-user", "--interactive=false"}, "User test-user created", []string{"pass"}); err != nil {
  303. cx.t.Fatal(err)
  304. }
  305. if err := spawnWithExpect(append(cx.PrefixArgs(), "role", "add", "test-role"), "Role test-role created"); err != nil {
  306. cx.t.Fatal(err)
  307. }
  308. if err := ctlV3User(cx, []string{"grant-role", "test-user", "test-role"}, "Role test-role is granted to user test-user", nil); err != nil {
  309. cx.t.Fatal(err)
  310. }
  311. cmd := append(cx.PrefixArgs(), "role", "grant-permission", "test-role", "readwrite", "foo")
  312. if err := spawnWithExpect(cmd, "Role test-role updated"); err != nil {
  313. cx.t.Fatal(err)
  314. }
  315. }
  316. func authTestTxn(cx ctlCtx) {
  317. // keys with 1 suffix aren't granted to test-user
  318. // keys with 2 suffix are granted to test-user
  319. keys := []string{"c1", "s1", "f1"}
  320. grantedKeys := []string{"c2", "s2", "f2"}
  321. for _, key := range keys {
  322. if err := ctlV3Put(cx, key, "v", ""); err != nil {
  323. cx.t.Fatal(err)
  324. }
  325. }
  326. for _, key := range grantedKeys {
  327. if err := ctlV3Put(cx, key, "v", ""); err != nil {
  328. cx.t.Fatal(err)
  329. }
  330. }
  331. if err := authEnable(cx); err != nil {
  332. cx.t.Fatal(err)
  333. }
  334. cx.user, cx.pass = "root", "root"
  335. authSetupTestUser(cx)
  336. // grant keys to test-user
  337. cx.user, cx.pass = "root", "root"
  338. for _, key := range grantedKeys {
  339. if err := ctlV3RoleGrantPermission(cx, "test-role", grantingPerm{true, true, key, "", false}); err != nil {
  340. cx.t.Fatal(err)
  341. }
  342. }
  343. // now test txn
  344. cx.interactive = true
  345. cx.user, cx.pass = "test-user", "pass"
  346. rqs := txnRequests{
  347. compare: []string{`version("c2") = "1"`},
  348. ifSucess: []string{"get s2"},
  349. ifFail: []string{"get f2"},
  350. results: []string{"SUCCESS", "s2", "v"},
  351. }
  352. if err := ctlV3Txn(cx, rqs); err != nil {
  353. cx.t.Fatal(err)
  354. }
  355. // a key of compare case isn't granted
  356. rqs = txnRequests{
  357. compare: []string{`version("c1") = "1"`},
  358. ifSucess: []string{"get s2"},
  359. ifFail: []string{"get f2"},
  360. results: []string{"Error: etcdserver: permission denied"},
  361. }
  362. if err := ctlV3Txn(cx, rqs); err != nil {
  363. cx.t.Fatal(err)
  364. }
  365. // a key of success case isn't granted
  366. rqs = txnRequests{
  367. compare: []string{`version("c2") = "1"`},
  368. ifSucess: []string{"get s1"},
  369. ifFail: []string{"get f2"},
  370. results: []string{"Error: etcdserver: permission denied"},
  371. }
  372. if err := ctlV3Txn(cx, rqs); err != nil {
  373. cx.t.Fatal(err)
  374. }
  375. // a key of failure case isn't granted
  376. rqs = txnRequests{
  377. compare: []string{`version("c2") = "1"`},
  378. ifSucess: []string{"get s2"},
  379. ifFail: []string{"get f1"},
  380. results: []string{"Error: etcdserver: permission denied"},
  381. }
  382. if err := ctlV3Txn(cx, rqs); err != nil {
  383. cx.t.Fatal(err)
  384. }
  385. }
  386. func authTestPrefixPerm(cx ctlCtx) {
  387. if err := authEnable(cx); err != nil {
  388. cx.t.Fatal(err)
  389. }
  390. cx.user, cx.pass = "root", "root"
  391. authSetupTestUser(cx)
  392. prefix := "/prefix/" // directory like prefix
  393. // grant keys to test-user
  394. cx.user, cx.pass = "root", "root"
  395. if err := ctlV3RoleGrantPermission(cx, "test-role", grantingPerm{true, true, prefix, "", true}); err != nil {
  396. cx.t.Fatal(err)
  397. }
  398. // try a prefix granted permission
  399. cx.user, cx.pass = "test-user", "pass"
  400. for i := 0; i < 10; i++ {
  401. key := fmt.Sprintf("%s%d", prefix, i)
  402. if err := ctlV3Put(cx, key, "val", ""); err != nil {
  403. cx.t.Fatal(err)
  404. }
  405. }
  406. if err := ctlV3PutFailPerm(cx, clientv3.GetPrefixRangeEnd(prefix), "baz"); err != nil {
  407. cx.t.Fatal(err)
  408. }
  409. // grant the entire keys to test-user
  410. cx.user, cx.pass = "root", "root"
  411. if err := ctlV3RoleGrantPermission(cx, "test-role", grantingPerm{true, true, "", "", true}); err != nil {
  412. cx.t.Fatal(err)
  413. }
  414. prefix2 := "/prefix2/"
  415. cx.user, cx.pass = "test-user", "pass"
  416. for i := 0; i < 10; i++ {
  417. key := fmt.Sprintf("%s%d", prefix2, i)
  418. if err := ctlV3Put(cx, key, "val", ""); err != nil {
  419. cx.t.Fatal(err)
  420. }
  421. }
  422. }
  423. func authTestMemberAdd(cx ctlCtx) {
  424. if err := authEnable(cx); err != nil {
  425. cx.t.Fatal(err)
  426. }
  427. cx.user, cx.pass = "root", "root"
  428. authSetupTestUser(cx)
  429. peerURL := fmt.Sprintf("http://localhost:%d", etcdProcessBasePort+11)
  430. // ordinary user cannot add a new member
  431. cx.user, cx.pass = "test-user", "pass"
  432. if err := ctlV3MemberAdd(cx, peerURL); err == nil {
  433. cx.t.Fatalf("ordinary user must not be allowed to add a member")
  434. }
  435. // root can add a new member
  436. cx.user, cx.pass = "root", "root"
  437. if err := ctlV3MemberAdd(cx, peerURL); err != nil {
  438. cx.t.Fatal(err)
  439. }
  440. }
  441. func authTestMemberRemove(cx ctlCtx) {
  442. if err := authEnable(cx); err != nil {
  443. cx.t.Fatal(err)
  444. }
  445. cx.user, cx.pass = "root", "root"
  446. authSetupTestUser(cx)
  447. ep, memIDToRemove, clusterID := cx.memberToRemove()
  448. // ordinary user cannot remove a member
  449. cx.user, cx.pass = "test-user", "pass"
  450. if err := ctlV3MemberRemove(cx, ep, memIDToRemove, clusterID); err == nil {
  451. cx.t.Fatalf("ordinary user must not be allowed to remove a member")
  452. }
  453. // root can remove a member
  454. cx.user, cx.pass = "root", "root"
  455. if err := ctlV3MemberRemove(cx, ep, memIDToRemove, clusterID); err != nil {
  456. cx.t.Fatal(err)
  457. }
  458. }
  459. func authTestMemberUpdate(cx ctlCtx) {
  460. if err := authEnable(cx); err != nil {
  461. cx.t.Fatal(err)
  462. }
  463. cx.user, cx.pass = "root", "root"
  464. authSetupTestUser(cx)
  465. mr, err := getMemberList(cx)
  466. if err != nil {
  467. cx.t.Fatal(err)
  468. }
  469. // ordinary user cannot update a member
  470. cx.user, cx.pass = "test-user", "pass"
  471. peerURL := fmt.Sprintf("http://localhost:%d", etcdProcessBasePort+11)
  472. memberID := fmt.Sprintf("%x", mr.Members[0].ID)
  473. if err = ctlV3MemberUpdate(cx, memberID, peerURL); err == nil {
  474. cx.t.Fatalf("ordinary user must not be allowed to update a member")
  475. }
  476. // root can update a member
  477. cx.user, cx.pass = "root", "root"
  478. if err = ctlV3MemberUpdate(cx, memberID, peerURL); err != nil {
  479. cx.t.Fatal(err)
  480. }
  481. }
  482. func authTestCertCN(cx ctlCtx) {
  483. if err := authEnable(cx); err != nil {
  484. cx.t.Fatal(err)
  485. }
  486. cx.user, cx.pass = "root", "root"
  487. if err := ctlV3User(cx, []string{"add", "example.com", "--interactive=false"}, "User example.com created", []string{""}); err != nil {
  488. cx.t.Fatal(err)
  489. }
  490. if err := spawnWithExpect(append(cx.PrefixArgs(), "role", "add", "test-role"), "Role test-role created"); err != nil {
  491. cx.t.Fatal(err)
  492. }
  493. if err := ctlV3User(cx, []string{"grant-role", "example.com", "test-role"}, "Role test-role is granted to user example.com", nil); err != nil {
  494. cx.t.Fatal(err)
  495. }
  496. // grant a new key
  497. if err := ctlV3RoleGrantPermission(cx, "test-role", grantingPerm{true, true, "hoo", "", false}); err != nil {
  498. cx.t.Fatal(err)
  499. }
  500. // try a granted key
  501. cx.user, cx.pass = "", ""
  502. if err := ctlV3Put(cx, "hoo", "bar", ""); err != nil {
  503. cx.t.Error(err)
  504. }
  505. // try a non granted key
  506. cx.user, cx.pass = "", ""
  507. if err := ctlV3PutFailPerm(cx, "baz", "bar"); err != nil {
  508. cx.t.Error(err)
  509. }
  510. }
  511. func authTestRevokeWithDelete(cx ctlCtx) {
  512. if err := authEnable(cx); err != nil {
  513. cx.t.Fatal(err)
  514. }
  515. cx.user, cx.pass = "root", "root"
  516. authSetupTestUser(cx)
  517. // create a new role
  518. cx.user, cx.pass = "root", "root"
  519. if err := ctlV3Role(cx, []string{"add", "test-role2"}, "Role test-role2 created"); err != nil {
  520. cx.t.Fatal(err)
  521. }
  522. // grant the new role to the user
  523. if err := ctlV3User(cx, []string{"grant-role", "test-user", "test-role2"}, "Role test-role2 is granted to user test-user", nil); err != nil {
  524. cx.t.Fatal(err)
  525. }
  526. // check the result
  527. if err := ctlV3User(cx, []string{"get", "test-user"}, "Roles: test-role test-role2", nil); err != nil {
  528. cx.t.Fatal(err)
  529. }
  530. // delete the role, test-role2 must be revoked from test-user
  531. if err := ctlV3Role(cx, []string{"delete", "test-role2"}, "Role test-role2 deleted"); err != nil {
  532. cx.t.Fatal(err)
  533. }
  534. // check the result
  535. if err := ctlV3User(cx, []string{"get", "test-user"}, "Roles: test-role", nil); err != nil {
  536. cx.t.Fatal(err)
  537. }
  538. }
  539. func authTestInvalidMgmt(cx ctlCtx) {
  540. if err := authEnable(cx); err != nil {
  541. cx.t.Fatal(err)
  542. }
  543. if err := ctlV3Role(cx, []string{"delete", "root"}, "Error: etcdserver: invalid auth management"); err == nil {
  544. cx.t.Fatal("deleting the role root must not be allowed")
  545. }
  546. if err := ctlV3User(cx, []string{"revoke-role", "root", "root"}, "Error: etcdserver: invalid auth management", []string{}); err == nil {
  547. cx.t.Fatal("revoking the role root from the user root must not be allowed")
  548. }
  549. }
  550. func authTestFromKeyPerm(cx ctlCtx) {
  551. if err := authEnable(cx); err != nil {
  552. cx.t.Fatal(err)
  553. }
  554. cx.user, cx.pass = "root", "root"
  555. authSetupTestUser(cx)
  556. // grant keys after z to test-user
  557. cx.user, cx.pass = "root", "root"
  558. if err := ctlV3RoleGrantPermission(cx, "test-role", grantingPerm{true, true, "z", "\x00", false}); err != nil {
  559. cx.t.Fatal(err)
  560. }
  561. // try the granted open ended permission
  562. cx.user, cx.pass = "test-user", "pass"
  563. for i := 0; i < 10; i++ {
  564. key := fmt.Sprintf("z%d", i)
  565. if err := ctlV3Put(cx, key, "val", ""); err != nil {
  566. cx.t.Fatal(err)
  567. }
  568. }
  569. largeKey := ""
  570. for i := 0; i < 10; i++ {
  571. largeKey += "\xff"
  572. if err := ctlV3Put(cx, largeKey, "val", ""); err != nil {
  573. cx.t.Fatal(err)
  574. }
  575. }
  576. // try a non granted key
  577. if err := ctlV3PutFailPerm(cx, "x", "baz"); err != nil {
  578. cx.t.Fatal(err)
  579. }
  580. // revoke the open ended permission
  581. cx.user, cx.pass = "root", "root"
  582. if err := ctlV3RoleRevokePermission(cx, "test-role", "z", "", true); err != nil {
  583. cx.t.Fatal(err)
  584. }
  585. // try the revoked open ended permission
  586. cx.user, cx.pass = "test-user", "pass"
  587. for i := 0; i < 10; i++ {
  588. key := fmt.Sprintf("z%d", i)
  589. if err := ctlV3PutFailPerm(cx, key, "val"); err != nil {
  590. cx.t.Fatal(err)
  591. }
  592. }
  593. // grant the entire keys
  594. cx.user, cx.pass = "root", "root"
  595. if err := ctlV3RoleGrantPermission(cx, "test-role", grantingPerm{true, true, "", "\x00", false}); err != nil {
  596. cx.t.Fatal(err)
  597. }
  598. // try keys, of course it must be allowed because test-role has a permission of the entire keys
  599. cx.user, cx.pass = "test-user", "pass"
  600. for i := 0; i < 10; i++ {
  601. key := fmt.Sprintf("z%d", i)
  602. if err := ctlV3Put(cx, key, "val", ""); err != nil {
  603. cx.t.Fatal(err)
  604. }
  605. }
  606. // revoke the entire keys
  607. cx.user, cx.pass = "root", "root"
  608. if err := ctlV3RoleRevokePermission(cx, "test-role", "", "", true); err != nil {
  609. cx.t.Fatal(err)
  610. }
  611. // try the revoked entire key permission
  612. cx.user, cx.pass = "test-user", "pass"
  613. for i := 0; i < 10; i++ {
  614. key := fmt.Sprintf("z%d", i)
  615. if err := ctlV3PutFailPerm(cx, key, "val"); err != nil {
  616. cx.t.Fatal(err)
  617. }
  618. }
  619. }
  620. func authLeaseTestKeepAlive(cx ctlCtx) {
  621. if err := authEnable(cx); err != nil {
  622. cx.t.Fatal(err)
  623. }
  624. cx.user, cx.pass = "root", "root"
  625. authSetupTestUser(cx)
  626. // put with TTL 10 seconds and keep-alive
  627. leaseID, err := ctlV3LeaseGrant(cx, 10)
  628. if err != nil {
  629. cx.t.Fatalf("leaseTestKeepAlive: ctlV3LeaseGrant error (%v)", err)
  630. }
  631. if err := ctlV3Put(cx, "key", "val", leaseID); err != nil {
  632. cx.t.Fatalf("leaseTestKeepAlive: ctlV3Put error (%v)", err)
  633. }
  634. if err := ctlV3LeaseKeepAlive(cx, leaseID); err != nil {
  635. cx.t.Fatalf("leaseTestKeepAlive: ctlV3LeaseKeepAlive error (%v)", err)
  636. }
  637. if err := ctlV3Get(cx, []string{"key"}, kv{"key", "val"}); err != nil {
  638. cx.t.Fatalf("leaseTestKeepAlive: ctlV3Get error (%v)", err)
  639. }
  640. }
  641. func authLeaseTestTimeToLiveExpired(cx ctlCtx) {
  642. if err := authEnable(cx); err != nil {
  643. cx.t.Fatal(err)
  644. }
  645. cx.user, cx.pass = "root", "root"
  646. authSetupTestUser(cx)
  647. ttl := 3
  648. if err := leaseTestTimeToLiveExpire(cx, ttl); err != nil {
  649. cx.t.Fatalf("leaseTestTimeToLiveExpire: error (%v)", err)
  650. }
  651. }
  652. func authLeaseTestLeaseGrantLeases(cx ctlCtx) {
  653. cx.user, cx.pass = "root", "root"
  654. authSetupTestUser(cx)
  655. if err := leaseTestGrantLeasesList(cx); err != nil {
  656. cx.t.Fatalf("authLeaseTestLeaseGrantLeases: error (%v)", err)
  657. }
  658. }
  659. func authLeaseTestLeaseRevoke(cx ctlCtx) {
  660. cx.user, cx.pass = "root", "root"
  661. authSetupTestUser(cx)
  662. if err := leaseTestRevoke(cx); err != nil {
  663. cx.t.Fatalf("authLeaseTestLeaseRevoke: error (%v)", err)
  664. }
  665. }
  666. func authTestWatch(cx ctlCtx) {
  667. if err := authEnable(cx); err != nil {
  668. cx.t.Fatal(err)
  669. }
  670. cx.user, cx.pass = "root", "root"
  671. authSetupTestUser(cx)
  672. // grant a key range
  673. if err := ctlV3RoleGrantPermission(cx, "test-role", grantingPerm{true, true, "key", "key4", false}); err != nil {
  674. cx.t.Fatal(err)
  675. }
  676. tests := []struct {
  677. puts []kv
  678. args []string
  679. wkv []kvExec
  680. want bool
  681. }{
  682. { // watch 1 key, should be successful
  683. []kv{{"key", "value"}},
  684. []string{"key", "--rev", "1"},
  685. []kvExec{{key: "key", val: "value"}},
  686. true,
  687. },
  688. { // watch 3 keys by range, should be successful
  689. []kv{{"key1", "val1"}, {"key3", "val3"}, {"key2", "val2"}},
  690. []string{"key", "key3", "--rev", "1"},
  691. []kvExec{{key: "key1", val: "val1"}, {key: "key2", val: "val2"}},
  692. true,
  693. },
  694. { // watch 1 key, should not be successful
  695. []kv{},
  696. []string{"key5", "--rev", "1"},
  697. []kvExec{},
  698. false,
  699. },
  700. { // watch 3 keys by range, should not be successful
  701. []kv{},
  702. []string{"key", "key6", "--rev", "1"},
  703. []kvExec{},
  704. false,
  705. },
  706. }
  707. cx.user, cx.pass = "test-user", "pass"
  708. for i, tt := range tests {
  709. donec := make(chan struct{})
  710. go func(i int, puts []kv) {
  711. defer close(donec)
  712. for j := range puts {
  713. if err := ctlV3Put(cx, puts[j].key, puts[j].val, ""); err != nil {
  714. cx.t.Fatalf("watchTest #%d-%d: ctlV3Put error (%v)", i, j, err)
  715. }
  716. }
  717. }(i, tt.puts)
  718. var err error
  719. if tt.want {
  720. err = ctlV3Watch(cx, tt.args, tt.wkv...)
  721. } else {
  722. err = ctlV3WatchFailPerm(cx, tt.args)
  723. }
  724. if err != nil {
  725. if cx.dialTimeout > 0 && !isGRPCTimedout(err) {
  726. cx.t.Errorf("watchTest #%d: ctlV3Watch error (%v)", i, err)
  727. }
  728. }
  729. <-donec
  730. }
  731. }
  732. func authTestRoleGet(cx ctlCtx) {
  733. if err := authEnable(cx); err != nil {
  734. cx.t.Fatal(err)
  735. }
  736. cx.user, cx.pass = "root", "root"
  737. authSetupTestUser(cx)
  738. expected := []string{
  739. "Role test-role",
  740. "KV Read:", "foo",
  741. "KV Write:", "foo",
  742. }
  743. if err := spawnWithExpects(append(cx.PrefixArgs(), "role", "get", "test-role"), expected...); err != nil {
  744. cx.t.Fatal(err)
  745. }
  746. // test-user can get the information of test-role because it belongs to the role
  747. cx.user, cx.pass = "test-user", "pass"
  748. if err := spawnWithExpects(append(cx.PrefixArgs(), "role", "get", "test-role"), expected...); err != nil {
  749. cx.t.Fatal(err)
  750. }
  751. // test-user cannot get the information of root because it doesn't belong to the role
  752. expected = []string{
  753. "Error: etcdserver: permission denied",
  754. }
  755. if err := spawnWithExpects(append(cx.PrefixArgs(), "role", "get", "root"), expected...); err != nil {
  756. cx.t.Fatal(err)
  757. }
  758. }
  759. func authTestUserGet(cx ctlCtx) {
  760. if err := authEnable(cx); err != nil {
  761. cx.t.Fatal(err)
  762. }
  763. cx.user, cx.pass = "root", "root"
  764. authSetupTestUser(cx)
  765. expected := []string{
  766. "User: test-user",
  767. "Roles: test-role",
  768. }
  769. if err := spawnWithExpects(append(cx.PrefixArgs(), "user", "get", "test-user"), expected...); err != nil {
  770. cx.t.Fatal(err)
  771. }
  772. // test-user can get the information of test-user itself
  773. cx.user, cx.pass = "test-user", "pass"
  774. if err := spawnWithExpects(append(cx.PrefixArgs(), "user", "get", "test-user"), expected...); err != nil {
  775. cx.t.Fatal(err)
  776. }
  777. // test-user cannot get the information of root
  778. expected = []string{
  779. "Error: etcdserver: permission denied",
  780. }
  781. if err := spawnWithExpects(append(cx.PrefixArgs(), "user", "get", "root"), expected...); err != nil {
  782. cx.t.Fatal(err)
  783. }
  784. }
  785. func authTestRoleList(cx ctlCtx) {
  786. if err := authEnable(cx); err != nil {
  787. cx.t.Fatal(err)
  788. }
  789. cx.user, cx.pass = "root", "root"
  790. authSetupTestUser(cx)
  791. if err := spawnWithExpect(append(cx.PrefixArgs(), "role", "list"), "test-role"); err != nil {
  792. cx.t.Fatal(err)
  793. }
  794. }
  795. func authTestDefrag(cx ctlCtx) {
  796. maintenanceInitKeys(cx)
  797. if err := authEnable(cx); err != nil {
  798. cx.t.Fatal(err)
  799. }
  800. cx.user, cx.pass = "root", "root"
  801. authSetupTestUser(cx)
  802. // ordinary user cannot defrag
  803. cx.user, cx.pass = "test-user", "pass"
  804. if err := ctlV3Defrag(cx); err == nil {
  805. cx.t.Fatal("ordinary user should not be able to issue a defrag request")
  806. }
  807. // root can defrag
  808. cx.user, cx.pass = "root", "root"
  809. if err := ctlV3Defrag(cx); err != nil {
  810. cx.t.Fatal(err)
  811. }
  812. }
  813. func authTestSnapshot(cx ctlCtx) {
  814. maintenanceInitKeys(cx)
  815. if err := authEnable(cx); err != nil {
  816. cx.t.Fatal(err)
  817. }
  818. cx.user, cx.pass = "root", "root"
  819. authSetupTestUser(cx)
  820. fpath := "test.snapshot"
  821. defer os.RemoveAll(fpath)
  822. // ordinary user cannot save a snapshot
  823. cx.user, cx.pass = "test-user", "pass"
  824. if err := ctlV3SnapshotSave(cx, fpath); err == nil {
  825. cx.t.Fatal("ordinary user should not be able to save a snapshot")
  826. }
  827. // root can save a snapshot
  828. cx.user, cx.pass = "root", "root"
  829. if err := ctlV3SnapshotSave(cx, fpath); err != nil {
  830. cx.t.Fatalf("snapshotTest ctlV3SnapshotSave error (%v)", err)
  831. }
  832. st, err := getSnapshotStatus(cx, fpath)
  833. if err != nil {
  834. cx.t.Fatalf("snapshotTest getSnapshotStatus error (%v)", err)
  835. }
  836. if st.Revision != 4 {
  837. cx.t.Fatalf("expected 4, got %d", st.Revision)
  838. }
  839. if st.TotalKey < 3 {
  840. cx.t.Fatalf("expected at least 3, got %d", st.TotalKey)
  841. }
  842. }
  843. func authTestEndpointHealth(cx ctlCtx) {
  844. if err := authEnable(cx); err != nil {
  845. cx.t.Fatal(err)
  846. }
  847. cx.user, cx.pass = "root", "root"
  848. authSetupTestUser(cx)
  849. if err := ctlV3EndpointHealth(cx); err != nil {
  850. cx.t.Fatalf("endpointStatusTest ctlV3EndpointHealth error (%v)", err)
  851. }
  852. // health checking with an ordinary user "succeeds" since permission denial goes through consensus
  853. cx.user, cx.pass = "test-user", "pass"
  854. if err := ctlV3EndpointHealth(cx); err != nil {
  855. cx.t.Fatalf("endpointStatusTest ctlV3EndpointHealth error (%v)", err)
  856. }
  857. // succeed if permissions granted for ordinary user
  858. cx.user, cx.pass = "root", "root"
  859. if err := ctlV3RoleGrantPermission(cx, "test-role", grantingPerm{true, true, "health", "", false}); err != nil {
  860. cx.t.Fatal(err)
  861. }
  862. cx.user, cx.pass = "test-user", "pass"
  863. if err := ctlV3EndpointHealth(cx); err != nil {
  864. cx.t.Fatalf("endpointStatusTest ctlV3EndpointHealth error (%v)", err)
  865. }
  866. }
  867. func authTestCertCNAndUsername(cx ctlCtx) {
  868. if err := authEnable(cx); err != nil {
  869. cx.t.Fatal(err)
  870. }
  871. cx.user, cx.pass = "root", "root"
  872. authSetupTestUser(cx)
  873. if err := ctlV3User(cx, []string{"add", "example.com", "--interactive=false"}, "User example.com created", []string{""}); err != nil {
  874. cx.t.Fatal(err)
  875. }
  876. if err := spawnWithExpect(append(cx.PrefixArgs(), "role", "add", "test-role-cn"), "Role test-role-cn created"); err != nil {
  877. cx.t.Fatal(err)
  878. }
  879. if err := ctlV3User(cx, []string{"grant-role", "example.com", "test-role-cn"}, "Role test-role-cn is granted to user example.com", nil); err != nil {
  880. cx.t.Fatal(err)
  881. }
  882. // grant a new key for CN based user
  883. if err := ctlV3RoleGrantPermission(cx, "test-role-cn", grantingPerm{true, true, "hoo", "", false}); err != nil {
  884. cx.t.Fatal(err)
  885. }
  886. // grant a new key for username based user
  887. if err := ctlV3RoleGrantPermission(cx, "test-role", grantingPerm{true, true, "bar", "", false}); err != nil {
  888. cx.t.Fatal(err)
  889. }
  890. // try a granted key for CN based user
  891. cx.user, cx.pass = "", ""
  892. if err := ctlV3Put(cx, "hoo", "bar", ""); err != nil {
  893. cx.t.Error(err)
  894. }
  895. // try a granted key for username based user
  896. cx.user, cx.pass = "test-user", "pass"
  897. if err := ctlV3Put(cx, "bar", "bar", ""); err != nil {
  898. cx.t.Error(err)
  899. }
  900. // try a non granted key for both of them
  901. cx.user, cx.pass = "", ""
  902. if err := ctlV3PutFailPerm(cx, "baz", "bar"); err != nil {
  903. cx.t.Error(err)
  904. }
  905. cx.user, cx.pass = "test-user", "pass"
  906. if err := ctlV3PutFailPerm(cx, "baz", "bar"); err != nil {
  907. cx.t.Error(err)
  908. }
  909. }