ctl_v3_auth_test.go 29 KB

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