github.com/bugraaydogar/snapd@v0.0.0-20210315170335-8c70bb858939/interfaces/policy/policy_test.go (about) 1 // -*- Mode: Go; indent-tabs-mode: t -*- 2 3 /* 4 * Copyright (C) 2016-2017 Canonical Ltd 5 * 6 * This program is free software: you can redistribute it and/or modify 7 * it under the terms of the GNU General Public License version 3 as 8 * published by the Free Software Foundation. 9 * 10 * This program is distributed in the hope that it will be useful, 11 * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 * GNU General Public License for more details. 14 * 15 * You should have received a copy of the GNU General Public License 16 * along with this program. If not, see <http://www.gnu.org/licenses/>. 17 * 18 */ 19 20 package policy_test 21 22 import ( 23 "strings" 24 "testing" 25 26 . "gopkg.in/check.v1" 27 28 "github.com/snapcore/snapd/asserts" 29 "github.com/snapcore/snapd/interfaces" 30 "github.com/snapcore/snapd/interfaces/policy" 31 "github.com/snapcore/snapd/release" 32 "github.com/snapcore/snapd/snap" 33 "github.com/snapcore/snapd/snap/snaptest" 34 ) 35 36 func TestPolicy(t *testing.T) { TestingT(t) } 37 38 type policySuite struct { 39 baseDecl *asserts.BaseDeclaration 40 41 plugSnap *snap.Info 42 slotSnap *snap.Info 43 44 plugDecl *asserts.SnapDeclaration 45 slotDecl *asserts.SnapDeclaration 46 47 randomSnap *snap.Info 48 randomDecl *asserts.SnapDeclaration 49 50 restoreSanitize func() 51 } 52 53 var _ = Suite(&policySuite{}) 54 55 func (s *policySuite) SetUpSuite(c *C) { 56 s.restoreSanitize = snap.MockSanitizePlugsSlots(func(snapInfo *snap.Info) {}) 57 a, err := asserts.Decode([]byte(`type: base-declaration 58 authority-id: canonical 59 series: 16 60 plugs: 61 base-plug-allow: true 62 base-plug-not-allow: 63 allow-connection: false 64 base-plug-not-allow-slots: 65 allow-connection: 66 slot-attributes: 67 s: S 68 base-plug-not-allow-plugs: 69 allow-connection: 70 plug-attributes: 71 p: P 72 base-plug-deny: 73 deny-connection: true 74 same-plug-publisher-id: 75 allow-connection: 76 slot-publisher-id: 77 - $PLUG_PUBLISHER_ID 78 plug-plug-attr: 79 allow-connection: 80 slot-attributes: 81 c: $PLUG(c) 82 plug-slot-attr: 83 allow-connection: 84 plug-attributes: 85 c: $SLOT(c) 86 plug-or: 87 allow-connection: 88 - 89 slot-attributes: 90 s: S1 91 plug-attributes: 92 p: P1 93 - 94 slot-attributes: 95 s: S2 96 plug-attributes: 97 p: P2 98 plug-on-classic-true: 99 allow-connection: 100 on-classic: true 101 plug-on-classic-distros: 102 allow-connection: 103 on-classic: 104 - ubuntu 105 - debian 106 plug-on-classic-false: 107 allow-connection: 108 on-classic: false 109 auto-base-plug-allow: true 110 auto-base-plug-not-allow: 111 allow-auto-connection: false 112 auto-base-plug-not-allow-slots: 113 allow-auto-connection: 114 slot-attributes: 115 s: S 116 auto-base-plug-not-allow-plugs: 117 allow-auto-connection: 118 plug-attributes: 119 p: P 120 auto-base-plug-deny: 121 deny-auto-connection: true 122 auto-plug-or: 123 allow-auto-connection: 124 - 125 slot-attributes: 126 s: S1 127 plug-attributes: 128 p: P1 129 - 130 slot-attributes: 131 s: S2 132 plug-attributes: 133 p: P2 134 auto-plug-on-store1: 135 allow-auto-connection: false 136 auto-plug-on-my-brand: 137 allow-auto-connection: false 138 auto-plug-on-my-model2: 139 allow-auto-connection: false 140 auto-plug-on-multi: 141 allow-auto-connection: false 142 install-plug-attr-ok: 143 allow-installation: 144 plug-attributes: 145 attr: ok 146 install-plug-gadget-only: 147 allow-installation: 148 plug-snap-type: 149 - gadget 150 install-plug-base-deny-snap-allow: 151 deny-installation: 152 plug-attributes: 153 attr: attrvalue 154 install-plug-or: 155 deny-installation: 156 - 157 plug-attributes: 158 p: P1 159 - 160 plug-snap-type: 161 - gadget 162 plug-attributes: 163 p: P2 164 install-plug-on-classic-distros: 165 allow-installation: 166 on-classic: 167 - ubuntu 168 - debian 169 install-plug-device-scope: 170 allow-installation: false 171 install-plug-name-bound: 172 allow-installation: 173 plug-names: 174 - $INTERFACE 175 slots: 176 base-slot-allow: true 177 base-slot-not-allow: 178 allow-connection: false 179 base-slot-not-allow-slots: 180 allow-connection: 181 slot-attributes: 182 s: S 183 base-slot-not-allow-plugs: 184 allow-connection: 185 plug-attributes: 186 p: P 187 base-slot-deny: 188 deny-connection: true 189 base-deny-snap-slot-allow: false 190 base-deny-snap-plug-allow: false 191 base-allow-snap-slot-not-allow: true 192 gadgethelp: 193 allow-connection: 194 plug-snap-type: 195 - gadget 196 same-slot-publisher-id: 197 allow-connection: 198 plug-publisher-id: 199 - $SLOT_PUBLISHER_ID 200 slot-slot-attr: 201 allow-connection: 202 plug-attributes: 203 a: 204 b: $SLOT(a.b) 205 slot-plug-attr: 206 allow-connection: 207 slot-attributes: 208 c: $PLUG(c) 209 slot-plug-missing: 210 allow-connection: 211 plug-attributes: 212 x: $MISSING 213 slot-or: 214 allow-connection: 215 - 216 slot-attributes: 217 s: S1 218 plug-attributes: 219 p: P1 220 - 221 slot-attributes: 222 s: S2 223 plug-attributes: 224 p: P2 225 slot-on-classic-true: 226 allow-connection: 227 on-classic: true 228 slot-on-classic-distros: 229 allow-connection: 230 on-classic: 231 - ubuntu 232 - debian 233 slot-on-classic-false: 234 allow-connection: 235 on-classic: false 236 auto-base-slot-allow: true 237 auto-base-slot-not-allow: 238 allow-auto-connection: false 239 auto-base-slot-not-allow-slots: 240 allow-auto-connection: 241 slot-attributes: 242 s: S 243 auto-base-slot-not-allow-plugs: 244 allow-auto-connection: 245 plug-attributes: 246 p: P 247 auto-base-slot-deny: 248 deny-auto-connection: true 249 auto-base-deny-snap-slot-allow: false 250 auto-base-deny-snap-plug-allow: false 251 auto-base-allow-snap-slot-not-allow: true 252 auto-slot-or: 253 allow-auto-connection: 254 - 255 slot-attributes: 256 s: S1 257 plug-attributes: 258 p: P1 259 - 260 slot-attributes: 261 s: S2 262 plug-attributes: 263 p: P2 264 auto-slot-on-store1: 265 allow-auto-connection: false 266 auto-slot-on-my-brand: 267 allow-auto-connection: false 268 auto-slot-on-my-model2: 269 allow-auto-connection: false 270 auto-slot-on-multi: 271 allow-auto-connection: false 272 install-slot-coreonly: 273 allow-installation: 274 slot-snap-type: 275 - core 276 install-slot-attr-ok: 277 allow-installation: 278 slot-attributes: 279 attr: ok 280 install-slot-attr-deny: 281 deny-installation: 282 slot-attributes: 283 trust: trusted 284 install-slot-base-deny-snap-allow: 285 deny-installation: 286 slot-attributes: 287 have: true 288 install-slot-or: 289 deny-installation: 290 - 291 slot-attributes: 292 p: P1 293 - 294 slot-snap-type: 295 - gadget 296 slot-attributes: 297 p: P2 298 install-slot-on-classic-distros: 299 allow-installation: 300 on-classic: 301 - ubuntu 302 - debian 303 install-slot-device-scope: 304 allow-installation: false 305 install-slot-name-bound: 306 allow-installation: 307 slot-names: 308 - $INTERFACE 309 slots-arity-default: 310 allow-auto-connection: true 311 slots-arity-slot-any: 312 deny-auto-connection: true 313 slots-arity-plug-any: 314 deny-auto-connection: true 315 slots-arity-slot-any-plug-one: 316 deny-auto-connection: true 317 slots-arity-slot-any-plug-two: 318 deny-auto-connection: true 319 slots-arity-slot-any-plug-default: 320 deny-auto-connection: true 321 slots-arity-slot-one-plug-any: 322 deny-auto-connection: true 323 slots-name-bound: 324 deny-auto-connection: true 325 plugs-name-bound: 326 deny-auto-connection: true 327 timestamp: 2016-09-30T12:00:00Z 328 sign-key-sha3-384: Jv8_JiHiIzJVcO9M55pPdqSDWUvuhfDIBJUS-3VW7F_idjix7Ffn5qMxB21ZQuij 329 330 AXNpZw==`)) 331 c.Assert(err, IsNil) 332 s.baseDecl = a.(*asserts.BaseDeclaration) 333 334 s.plugSnap = snaptest.MockInfo(c, ` 335 name: plug-snap 336 version: 0 337 plugs: 338 random: 339 mismatchy: 340 interface: bar 341 342 base-plug-allow: 343 base-plug-not-allow: 344 base-plug-not-allow-slots: 345 base-plug-not-allow-plugs: 346 base-plug-deny: 347 348 base-slot-allow: 349 base-slot-not-allow: 350 base-slot-not-allow-slots: 351 base-slot-not-allow-plugs: 352 base-slot-deny: 353 354 auto-base-plug-allow: 355 auto-base-plug-not-allow: 356 auto-base-plug-not-allow-slots: 357 auto-base-plug-not-allow-plugs: 358 auto-base-plug-deny: 359 360 auto-base-slot-allow: 361 auto-base-slot-not-allow: 362 auto-base-slot-not-allow-slots: 363 auto-base-slot-not-allow-plugs: 364 auto-base-slot-deny: 365 366 snap-plug-allow: 367 snap-plug-not-allow: 368 snap-plug-deny: 369 370 snap-slot-allow: 371 snap-slot-not-allow: 372 snap-slot-deny: 373 374 base-deny-snap-slot-allow: 375 base-deny-snap-plug-allow: 376 base-allow-snap-slot-not-allow: 377 378 snap-slot-deny-snap-plug-allow: 379 380 auto-snap-plug-allow: 381 auto-snap-plug-not-allow: 382 auto-snap-plug-deny: 383 384 auto-snap-slot-allow: 385 auto-snap-slot-not-allow: 386 auto-snap-slot-deny: 387 388 auto-base-deny-snap-slot-allow: 389 auto-base-deny-snap-plug-allow: 390 auto-base-allow-snap-slot-not-allow: 391 392 auto-snap-slot-deny-snap-plug-allow: 393 394 gadgethelp: 395 trustedhelp: 396 397 precise-plug-snap-id: 398 precise-slot-snap-id: 399 400 checked-plug-publisher-id: 401 checked-slot-publisher-id: 402 403 same-plug-publisher-id: 404 405 slot-slot-attr-mismatch: 406 interface: slot-slot-attr 407 a: 408 b: [] 409 410 slot-slot-attr-match: 411 interface: slot-slot-attr 412 a: 413 b: ["x", "y"] 414 415 slot-plug-attr-mismatch: 416 interface: slot-plug-attr 417 c: "Z" 418 419 slot-plug-attr-dynamic: 420 interface: slot-plug-attr 421 422 slot-plug-attr-match: 423 interface: slot-plug-attr 424 c: "C" 425 426 slot-plug-missing-mismatch: 427 interface: slot-plug-missing 428 x: 1 429 z: 2 430 431 slot-plug-missing-match: 432 interface: slot-plug-missing 433 z: 2 434 435 plug-plug-attr: 436 c: "C" 437 438 plug-slot-attr: 439 c: "C" 440 441 plug-or-p1-s1: 442 interface: plug-or 443 p: P1 444 445 plug-or-p2-s2: 446 interface: plug-or 447 p: P2 448 449 plug-or-p1-s2: 450 interface: plug-or 451 p: P1 452 453 auto-plug-or-p1-s1: 454 interface: auto-plug-or 455 p: P1 456 457 auto-plug-or-p2-s2: 458 interface: auto-plug-or 459 p: P2 460 461 auto-plug-or-p2-s1: 462 interface: auto-plug-or 463 p: P2 464 465 auto-plug-on-store1: 466 auto-plug-on-my-brand: 467 auto-plug-on-my-model2: 468 auto-plug-on-multi: 469 470 slot-or-p1-s1: 471 interface: slot-or 472 p: P1 473 474 slot-or-p2-s2: 475 interface: slot-or 476 p: P2 477 478 slot-or-p1-s2: 479 interface: slot-or 480 p: P1 481 482 auto-slot-or-p1-s1: 483 interface: auto-slot-or 484 p: P1 485 486 auto-slot-or-p2-s2: 487 interface: auto-slot-or 488 p: P2 489 490 auto-slot-or-p2-s1: 491 interface: auto-slot-or 492 p: P2 493 494 auto-slot-on-store1: 495 auto-slot-on-my-brand: 496 auto-slot-on-my-model2: 497 auto-slot-on-multi: 498 499 slot-on-classic-true: 500 slot-on-classic-distros: 501 slot-on-classic-false: 502 503 plug-on-classic-true: 504 plug-on-classic-distros: 505 plug-on-classic-false: 506 507 slots-arity-default: 508 slots-arity-slot-any: 509 slots-arity-plug-any: 510 slots-arity-slot-any-plug-one: 511 slots-arity-slot-any-plug-two: 512 slots-arity-slot-any-plug-default: 513 slots-arity-slot-one-plug-any: 514 515 slots-name-bound-p1: 516 interface: slots-name-bound 517 slots-name-bound-p2: 518 interface: slots-name-bound 519 plugs-name-bound-p1: 520 interface: plugs-name-bound 521 plugs-name-bound-p2: 522 interface: plugs-name-bound 523 `, nil) 524 525 s.slotSnap = snaptest.MockInfo(c, ` 526 name: slot-snap 527 version: 0 528 slots: 529 random: 530 mismatchy: 531 interface: baz 532 533 base-plug-allow: 534 base-plug-not-allow: 535 base-plug-not-allow-slots: 536 base-plug-not-allow-plugs: 537 base-plug-deny: 538 539 base-slot-allow: 540 base-slot-not-allow: 541 base-slot-not-allow-slots: 542 base-slot-not-allow-plugs: 543 base-slot-deny: 544 545 auto-base-plug-allow: 546 auto-base-plug-not-allow: 547 auto-base-plug-not-allow-slots: 548 auto-base-plug-not-allow-plugs: 549 auto-base-plug-deny: 550 551 auto-base-slot-allow: 552 auto-base-slot-not-allow: 553 auto-base-slot-not-allow-slots: 554 auto-base-slot-not-allow-plugs: 555 auto-base-slot-deny: 556 557 snap-plug-allow: 558 snap-plug-not-allow: 559 snap-plug-deny: 560 561 snap-slot-allow: 562 snap-slot-not-allow: 563 snap-slot-deny: 564 565 base-deny-snap-slot-allow: 566 base-deny-snap-plug-allow: 567 base-allow-snap-slot-not-allow: 568 569 snap-slot-deny-snap-plug-allow: 570 571 auto-snap-plug-allow: 572 auto-snap-plug-not-allow: 573 auto-snap-plug-deny: 574 575 auto-snap-slot-allow: 576 auto-snap-slot-not-allow: 577 auto-snap-slot-deny: 578 579 auto-base-deny-snap-slot-allow: 580 auto-base-deny-snap-plug-allow: 581 auto-base-allow-snap-slot-not-allow: 582 583 auto-snap-slot-deny-snap-plug-allow: 584 585 trustedhelp: 586 587 precise-plug-snap-id: 588 precise-slot-snap-id: 589 590 checked-plug-publisher-id: 591 checked-slot-publisher-id: 592 593 same-slot-publisher-id: 594 595 slot-slot-attr: 596 a: 597 b: ["x", "y"] 598 599 slot-plug-attr: 600 c: "C" 601 602 slot-plug-missing: 603 604 plug-plug-attr-mismatch: 605 interface: plug-plug-attr 606 c: "Z" 607 608 plug-plug-attr-match: 609 interface: plug-plug-attr 610 c: "C" 611 612 plug-plug-attr-dynamic: 613 interface: plug-plug-attr 614 615 plug-slot-attr-mismatch: 616 interface: plug-slot-attr 617 c: "Z" 618 619 plug-slot-attr-match: 620 interface: plug-slot-attr 621 c: "C" 622 623 plug-or-p1-s1: 624 interface: plug-or 625 s: S1 626 627 plug-or-p2-s2: 628 interface: plug-or 629 s: S2 630 631 plug-or-p1-s2: 632 interface: plug-or 633 s: S2 634 635 auto-plug-or-p1-s1: 636 interface: auto-plug-or 637 s: S1 638 639 auto-plug-or-p2-s2: 640 interface: auto-plug-or 641 s: S2 642 643 auto-plug-or-p2-s1: 644 interface: auto-plug-or 645 s: S1 646 647 auto-plug-on-store1: 648 auto-plug-on-my-brand: 649 auto-plug-on-my-model2: 650 auto-plug-on-multi: 651 652 slot-or-p1-s1: 653 interface: slot-or 654 s: S1 655 656 slot-or-p2-s2: 657 interface: slot-or 658 s: S2 659 660 slot-or-p1-s2: 661 interface: slot-or 662 s: S2 663 664 auto-slot-or-p1-s1: 665 interface: auto-slot-or 666 s: S1 667 668 auto-slot-or-p2-s2: 669 interface: auto-slot-or 670 s: S2 671 672 auto-slot-or-p2-s1: 673 interface: auto-slot-or 674 s: S1 675 676 auto-slot-on-store1: 677 auto-slot-on-my-brand: 678 auto-slot-on-my-model2: 679 auto-slot-on-multi: 680 681 slot-on-classic-true: 682 slot-on-classic-distros: 683 slot-on-classic-false: 684 685 plug-on-classic-true: 686 plug-on-classic-distros: 687 plug-on-classic-false: 688 689 slots-arity-default: 690 slots-arity-slot-any: 691 slots-arity-plug-any: 692 slots-arity-slot-any-plug-one: 693 slots-arity-slot-any-plug-two: 694 slots-arity-slot-any-plug-default: 695 slots-arity-slot-one-plug-any: 696 697 slots-name-bound-s1: 698 interface: slots-name-bound 699 slots-name-bound-s2: 700 interface: slots-name-bound 701 plugs-name-bound-s1: 702 interface: plugs-name-bound 703 plugs-name-bound-s2: 704 interface: plugs-name-bound 705 706 `, nil) 707 708 a, err = asserts.Decode([]byte(`type: snap-declaration 709 authority-id: canonical 710 series: 16 711 snap-name: plug-snap 712 snap-id: plugsnapidididididididididididid 713 publisher-id: plug-publisher 714 plugs: 715 snap-plug-allow: true 716 snap-plug-deny: false 717 snap-plug-not-allow: 718 allow-connection: false 719 base-deny-snap-plug-allow: true 720 snap-slot-deny-snap-plug-allow: 721 deny-connection: false 722 trustedhelp: 723 allow-connection: 724 slot-snap-type: 725 - core 726 - gadget 727 precise-slot-snap-id: 728 allow-connection: 729 slot-snap-id: 730 - slotsnapidididididididididididid 731 checked-slot-publisher-id: 732 allow-connection: 733 slot-publisher-id: 734 - slot-publisher 735 - $PLUG_PUBLISHER_ID 736 auto-snap-plug-allow: true 737 auto-snap-plug-deny: false 738 auto-snap-plug-not-allow: 739 allow-auto-connection: false 740 auto-snap-slot-deny-snap-plug-allow: 741 deny-auto-connection: false 742 auto-base-deny-snap-plug-allow: true 743 auto-plug-on-store1: 744 allow-auto-connection: 745 on-store: 746 - store1 747 auto-plug-on-my-brand: 748 allow-auto-connection: 749 on-brand: 750 - my-brand 751 - my-brand-subbrand 752 auto-plug-on-my-model2: 753 allow-auto-connection: 754 on-model: 755 - my-brand-subbrand/my-model2 756 auto-plug-on-multi: 757 allow-auto-connection: 758 on-brand: 759 - my-brand 760 - my-brand-subbrand 761 on-store: 762 - store1 763 - other-store 764 on-model: 765 - my-brand/my-model1 766 - my-brand-subbrand/my-model2 767 slots-arity-plug-any: 768 allow-auto-connection: 769 slots-per-plug: * 770 slots-arity-slot-any-plug-one: 771 allow-auto-connection: 772 slots-per-plug: 1 773 slots-arity-slot-any-plug-two: 774 allow-auto-connection: 775 slots-per-plug: 2 776 slots-arity-slot-any-plug-default: 777 allow-auto-connection: true 778 slots-arity-slot-one-plug-any: 779 allow-auto-connection: 780 slots-per-plug: * 781 plugs-name-bound: 782 allow-auto-connection: 783 - 784 plug-names: 785 - plugs-name-bound-p1 786 slot-names: 787 - plugs-name-bound-s2 788 timestamp: 2016-09-30T12:00:00Z 789 sign-key-sha3-384: Jv8_JiHiIzJVcO9M55pPdqSDWUvuhfDIBJUS-3VW7F_idjix7Ffn5qMxB21ZQuij 790 791 AXNpZw==`)) 792 c.Assert(err, IsNil) 793 s.plugDecl = a.(*asserts.SnapDeclaration) 794 795 a, err = asserts.Decode([]byte(`type: snap-declaration 796 authority-id: canonical 797 series: 16 798 snap-name: slot-snap 799 snap-id: slotsnapidididididididididididid 800 publisher-id: slot-publisher 801 slots: 802 snap-slot-allow: true 803 snap-slot-deny: false 804 snap-slot-not-allow: 805 allow-connection: false 806 base-deny-snap-slot-allow: true 807 snap-slot-deny-snap-plug-allow: 808 deny-connection: true 809 base-allow-snap-slot-not-allow: 810 allow-connection: false 811 precise-plug-snap-id: 812 allow-connection: 813 plug-snap-id: 814 - plugsnapidididididididididididid 815 checked-plug-publisher-id: 816 allow-connection: 817 plug-publisher-id: 818 - plug-publisher 819 auto-snap-slot-allow: true 820 auto-snap-slot-deny: false 821 auto-snap-slot-not-allow: 822 allow-auto-connection: false 823 auto-base-deny-snap-slot-allow: true 824 auto-snap-slot-deny-snap-plug-allow: 825 deny-auto-connection: true 826 auto-base-allow-snap-slot-not-allow: 827 allow-auto-connection: false 828 auto-slot-on-store1: 829 allow-auto-connection: 830 on-store: 831 - store1 832 auto-slot-on-my-brand: 833 allow-auto-connection: 834 on-brand: 835 - my-brand 836 - my-brand-subbrand 837 auto-slot-on-my-model2: 838 allow-auto-connection: 839 on-model: 840 - my-brand-subbrand/my-model2 841 auto-slot-on-multi: 842 allow-auto-connection: 843 on-brand: 844 - my-brand 845 - my-brand-subbrand 846 on-store: 847 - store1 848 - other-store 849 on-model: 850 - my-brand/my-model1 851 - my-brand-subbrand/my-model2 852 slots-arity-slot-any: 853 allow-auto-connection: 854 slots-per-plug: * 855 slots-arity-slot-any-plug-one: 856 allow-auto-connection: 857 slots-per-plug: * 858 slots-arity-slot-any-plug-two: 859 allow-auto-connection: 860 slots-per-plug: * 861 slots-arity-slot-any-plug-default: 862 allow-auto-connection: 863 slots-per-plug: * 864 slots-arity-slot-one-plug-any: 865 allow-auto-connection: 866 slots-per-plug: 1 867 slots-name-bound: 868 allow-auto-connection: 869 - 870 plug-names: 871 - slots-name-bound-p2 872 slot-names: 873 - slots-name-bound-s2 874 timestamp: 2016-09-30T12:00:00Z 875 sign-key-sha3-384: Jv8_JiHiIzJVcO9M55pPdqSDWUvuhfDIBJUS-3VW7F_idjix7Ffn5qMxB21ZQuij 876 877 AXNpZw==`)) 878 c.Assert(err, IsNil) 879 s.slotDecl = a.(*asserts.SnapDeclaration) 880 881 s.randomSnap = snaptest.MockInfo(c, ` 882 name: random-snap 883 version: 0 884 plugs: 885 precise-plug-snap-id: 886 checked-plug-publisher-id: 887 same-slot-publisher-id: 888 slot-slot-attr: 889 slots: 890 precise-slot-snap-id: 891 checked-slot-publisher-id: 892 same-plug-publisher-id: 893 `, nil) 894 895 a, err = asserts.Decode([]byte(`type: snap-declaration 896 authority-id: canonical 897 series: 16 898 snap-name: random-snap 899 snap-id: randomsnapididididididididid 900 publisher-id: random-publisher 901 timestamp: 2016-09-30T12:00:00Z 902 sign-key-sha3-384: Jv8_JiHiIzJVcO9M55pPdqSDWUvuhfDIBJUS-3VW7F_idjix7Ffn5qMxB21ZQuij 903 904 AXNpZw==`)) 905 c.Assert(err, IsNil) 906 s.randomDecl = a.(*asserts.SnapDeclaration) 907 } 908 909 func (s *policySuite) TearDownSuite(c *C) { 910 s.restoreSanitize() 911 } 912 913 func (s *policySuite) TestBaselineDefaultIsAllow(c *C) { 914 cand := policy.ConnectCandidate{ 915 Plug: interfaces.NewConnectedPlug(s.plugSnap.Plugs["random"], nil, nil), 916 Slot: interfaces.NewConnectedSlot(s.slotSnap.Slots["random"], nil, nil), 917 BaseDeclaration: s.baseDecl, 918 } 919 920 c.Check(cand.Check(), IsNil) 921 arity, err := cand.CheckAutoConnect() 922 c.Check(err, IsNil) 923 c.Check(arity.SlotsPerPlugAny(), Equals, false) 924 } 925 926 func (s *policySuite) TestInterfaceMismatch(c *C) { 927 cand := policy.ConnectCandidate{ 928 Plug: interfaces.NewConnectedPlug(s.plugSnap.Plugs["mismatchy"], nil, nil), 929 Slot: interfaces.NewConnectedSlot(s.slotSnap.Slots["mismatchy"], nil, nil), 930 BaseDeclaration: s.baseDecl, 931 } 932 933 c.Check(cand.Check(), ErrorMatches, `cannot connect mismatched plug interface "bar" to slot interface "baz"`) 934 } 935 936 func (s *policySuite) TestBaseDeclAllowDenyConnection(c *C) { 937 tests := []struct { 938 iface string 939 expected string // "" => no error 940 }{ 941 {"base-plug-allow", ""}, 942 {"base-plug-deny", `connection denied by plug rule of interface "base-plug-deny"`}, 943 {"base-plug-not-allow", `connection not allowed by plug rule of interface "base-plug-not-allow"`}, 944 {"base-slot-allow", ""}, 945 {"base-slot-deny", `connection denied by slot rule of interface "base-slot-deny"`}, 946 {"base-slot-not-allow", `connection not allowed by slot rule of interface "base-slot-not-allow"`}, 947 {"base-plug-not-allow-slots", `connection not allowed.*`}, 948 {"base-slot-not-allow-slots", `connection not allowed.*`}, 949 {"base-plug-not-allow-plugs", `connection not allowed.*`}, 950 {"base-slot-not-allow-plugs", `connection not allowed.*`}, 951 {"plug-or-p1-s1", ""}, 952 {"plug-or-p2-s2", ""}, 953 {"plug-or-p1-s2", "connection not allowed by plug rule.*"}, 954 {"slot-or-p1-s1", ""}, 955 {"slot-or-p2-s2", ""}, 956 {"slot-or-p1-s2", "connection not allowed by slot rule.*"}, 957 } 958 959 for _, t := range tests { 960 cand := policy.ConnectCandidate{ 961 Plug: interfaces.NewConnectedPlug(s.plugSnap.Plugs[t.iface], nil, nil), 962 Slot: interfaces.NewConnectedSlot(s.slotSnap.Slots[t.iface], nil, nil), 963 BaseDeclaration: s.baseDecl, 964 } 965 966 err := cand.Check() 967 if t.expected == "" { 968 c.Check(err, IsNil) 969 } else { 970 c.Check(err, ErrorMatches, t.expected) 971 } 972 } 973 } 974 975 func (s *policySuite) TestBaseDeclAllowDenyAutoConnection(c *C) { 976 tests := []struct { 977 iface string 978 expected string // "" => no error 979 }{ 980 {"auto-base-plug-allow", ""}, 981 {"auto-base-plug-deny", `auto-connection denied by plug rule of interface "auto-base-plug-deny"`}, 982 {"auto-base-plug-not-allow", `auto-connection not allowed by plug rule of interface "auto-base-plug-not-allow"`}, 983 {"auto-base-slot-allow", ""}, 984 {"auto-base-slot-deny", `auto-connection denied by slot rule of interface "auto-base-slot-deny"`}, 985 {"auto-base-slot-not-allow", `auto-connection not allowed by slot rule of interface "auto-base-slot-not-allow"`}, 986 {"auto-base-plug-not-allow-slots", `auto-connection not allowed.*`}, 987 {"auto-base-slot-not-allow-slots", `auto-connection not allowed.*`}, 988 {"auto-base-plug-not-allow-plugs", `auto-connection not allowed.*`}, 989 {"auto-base-slot-not-allow-plugs", `auto-connection not allowed.*`}, 990 {"auto-plug-or-p1-s1", ""}, 991 {"auto-plug-or-p2-s2", ""}, 992 {"auto-plug-or-p2-s1", "auto-connection not allowed by plug rule.*"}, 993 {"auto-slot-or-p1-s1", ""}, 994 {"auto-slot-or-p2-s2", ""}, 995 {"auto-slot-or-p2-s1", "auto-connection not allowed by slot rule.*"}, 996 } 997 998 for _, t := range tests { 999 cand := policy.ConnectCandidate{ 1000 Plug: interfaces.NewConnectedPlug(s.plugSnap.Plugs[t.iface], nil, nil), 1001 Slot: interfaces.NewConnectedSlot(s.slotSnap.Slots[t.iface], nil, nil), 1002 BaseDeclaration: s.baseDecl, 1003 } 1004 1005 arity, err := cand.CheckAutoConnect() 1006 if t.expected == "" { 1007 c.Check(err, IsNil) 1008 c.Check(arity.SlotsPerPlugAny(), Equals, false) 1009 } else { 1010 c.Check(err, ErrorMatches, t.expected) 1011 } 1012 } 1013 } 1014 1015 func (s *policySuite) TestSnapDeclAllowDenyConnection(c *C) { 1016 tests := []struct { 1017 iface string 1018 expected string // "" => no error 1019 }{ 1020 {"random", ""}, 1021 {"snap-plug-allow", ""}, 1022 {"snap-plug-deny", `connection denied by plug rule of interface "snap-plug-deny" for "plug-snap" snap`}, 1023 {"snap-plug-not-allow", `connection not allowed by plug rule of interface "snap-plug-not-allow" for "plug-snap" snap`}, 1024 {"snap-slot-allow", ""}, 1025 {"snap-slot-deny", `connection denied by slot rule of interface "snap-slot-deny" for "slot-snap" snap`}, 1026 {"snap-slot-not-allow", `connection not allowed by slot rule of interface "snap-slot-not-allow" for "slot-snap" snap`}, 1027 {"base-deny-snap-slot-allow", ""}, 1028 {"base-deny-snap-plug-allow", ""}, 1029 {"snap-slot-deny-snap-plug-allow", ""}, 1030 {"base-allow-snap-slot-not-allow", `connection not allowed.*`}, 1031 } 1032 1033 for _, t := range tests { 1034 cand := policy.ConnectCandidate{ 1035 Plug: interfaces.NewConnectedPlug(s.plugSnap.Plugs[t.iface], nil, nil), 1036 Slot: interfaces.NewConnectedSlot(s.slotSnap.Slots[t.iface], nil, nil), 1037 PlugSnapDeclaration: s.plugDecl, 1038 SlotSnapDeclaration: s.slotDecl, 1039 BaseDeclaration: s.baseDecl, 1040 } 1041 1042 err := cand.Check() 1043 if t.expected == "" { 1044 c.Check(err, IsNil) 1045 } else { 1046 c.Check(err, ErrorMatches, t.expected) 1047 } 1048 } 1049 } 1050 1051 func (s *policySuite) TestSnapDeclAllowDenyAutoConnection(c *C) { 1052 tests := []struct { 1053 iface string 1054 expected string // "" => no error 1055 }{ 1056 {"random", ""}, 1057 {"auto-snap-plug-allow", ""}, 1058 {"auto-snap-plug-deny", `auto-connection denied by plug rule of interface "auto-snap-plug-deny" for "plug-snap" snap`}, 1059 {"auto-snap-plug-not-allow", `auto-connection not allowed by plug rule of interface "auto-snap-plug-not-allow" for "plug-snap" snap`}, 1060 {"auto-snap-slot-allow", ""}, 1061 {"auto-snap-slot-deny", `auto-connection denied by slot rule of interface "auto-snap-slot-deny" for "slot-snap" snap`}, 1062 {"auto-snap-slot-not-allow", `auto-connection not allowed by slot rule of interface "auto-snap-slot-not-allow" for "slot-snap" snap`}, 1063 {"auto-base-deny-snap-slot-allow", ""}, 1064 {"auto-base-deny-snap-plug-allow", ""}, 1065 {"auto-snap-slot-deny-snap-plug-allow", ""}, 1066 {"auto-base-allow-snap-slot-not-allow", `auto-connection not allowed.*`}, 1067 } 1068 1069 for _, t := range tests { 1070 cand := policy.ConnectCandidate{ 1071 Plug: interfaces.NewConnectedPlug(s.plugSnap.Plugs[t.iface], nil, nil), 1072 Slot: interfaces.NewConnectedSlot(s.slotSnap.Slots[t.iface], nil, nil), 1073 PlugSnapDeclaration: s.plugDecl, 1074 SlotSnapDeclaration: s.slotDecl, 1075 BaseDeclaration: s.baseDecl, 1076 } 1077 1078 arity, err := cand.CheckAutoConnect() 1079 if t.expected == "" { 1080 c.Check(err, IsNil) 1081 c.Check(arity.SlotsPerPlugAny(), Equals, false) 1082 } else { 1083 c.Check(err, ErrorMatches, t.expected) 1084 } 1085 } 1086 } 1087 1088 func (s *policySuite) TestSnapTypeCheckConnection(c *C) { 1089 gadgetSnap := snaptest.MockInfo(c, ` 1090 name: gadget 1091 version: 0 1092 type: gadget 1093 plugs: 1094 gadgethelp: 1095 slots: 1096 trustedhelp: 1097 `, nil) 1098 1099 coreSnap := snaptest.MockInfo(c, ` 1100 name: core 1101 version: 0 1102 type: os 1103 slots: 1104 gadgethelp: 1105 trustedhelp: 1106 `, nil) 1107 1108 cand := policy.ConnectCandidate{ 1109 Plug: interfaces.NewConnectedPlug(gadgetSnap.Plugs["gadgethelp"], nil, nil), 1110 Slot: interfaces.NewConnectedSlot(coreSnap.Slots["gadgethelp"], nil, nil), 1111 BaseDeclaration: s.baseDecl, 1112 } 1113 c.Check(cand.Check(), IsNil) 1114 1115 cand = policy.ConnectCandidate{ 1116 Plug: interfaces.NewConnectedPlug(s.plugSnap.Plugs["gadgethelp"], nil, nil), 1117 Slot: interfaces.NewConnectedSlot(coreSnap.Slots["gadgethelp"], nil, nil), 1118 BaseDeclaration: s.baseDecl, 1119 } 1120 c.Check(cand.Check(), ErrorMatches, "connection not allowed.*") 1121 1122 for _, trustedSide := range []*snap.Info{coreSnap, gadgetSnap} { 1123 cand = policy.ConnectCandidate{ 1124 Plug: interfaces.NewConnectedPlug(s.plugSnap.Plugs["trustedhelp"], nil, nil), 1125 PlugSnapDeclaration: s.plugDecl, 1126 Slot: interfaces.NewConnectedSlot(trustedSide.Slots["trustedhelp"], nil, nil), 1127 BaseDeclaration: s.baseDecl, 1128 } 1129 c.Check(cand.Check(), IsNil) 1130 } 1131 1132 cand = policy.ConnectCandidate{ 1133 Plug: interfaces.NewConnectedPlug(s.plugSnap.Plugs["trustedhelp"], nil, nil), 1134 PlugSnapDeclaration: s.plugDecl, 1135 Slot: interfaces.NewConnectedSlot(s.slotSnap.Slots["trustedhelp"], nil, nil), 1136 BaseDeclaration: s.baseDecl, 1137 } 1138 c.Check(cand.Check(), ErrorMatches, "connection not allowed.*") 1139 } 1140 1141 func (s *policySuite) TestPlugSnapIDCheckConnection(c *C) { 1142 // no plug-side declaration 1143 cand := policy.ConnectCandidate{ 1144 Plug: interfaces.NewConnectedPlug(s.randomSnap.Plugs["precise-plug-snap-id"], nil, nil), 1145 Slot: interfaces.NewConnectedSlot(s.slotSnap.Slots["precise-plug-snap-id"], nil, nil), 1146 SlotSnapDeclaration: s.slotDecl, 1147 BaseDeclaration: s.baseDecl, 1148 } 1149 c.Check(cand.Check(), ErrorMatches, "connection not allowed.*") 1150 1151 // plug-side declaration, wrong snap-id 1152 cand = policy.ConnectCandidate{ 1153 Plug: interfaces.NewConnectedPlug(s.randomSnap.Plugs["precise-plug-snap-id"], nil, nil), 1154 PlugSnapDeclaration: s.randomDecl, 1155 Slot: interfaces.NewConnectedSlot(s.slotSnap.Slots["precise-plug-snap-id"], nil, nil), 1156 SlotSnapDeclaration: s.slotDecl, 1157 BaseDeclaration: s.baseDecl, 1158 } 1159 c.Check(cand.Check(), ErrorMatches, "connection not allowed.*") 1160 1161 // right snap-id 1162 cand = policy.ConnectCandidate{ 1163 Plug: interfaces.NewConnectedPlug(s.plugSnap.Plugs["precise-plug-snap-id"], nil, nil), 1164 PlugSnapDeclaration: s.plugDecl, 1165 Slot: interfaces.NewConnectedSlot(s.slotSnap.Slots["precise-plug-snap-id"], nil, nil), 1166 SlotSnapDeclaration: s.slotDecl, 1167 BaseDeclaration: s.baseDecl, 1168 } 1169 c.Check(cand.Check(), IsNil) 1170 } 1171 1172 func (s *policySuite) TestSlotSnapIDCheckConnection(c *C) { 1173 // no slot-side declaration 1174 cand := policy.ConnectCandidate{ 1175 Plug: interfaces.NewConnectedPlug(s.plugSnap.Plugs["precise-slot-snap-id"], nil, nil), 1176 PlugSnapDeclaration: s.plugDecl, 1177 Slot: interfaces.NewConnectedSlot(s.randomSnap.Slots["precise-slot-snap-id"], nil, nil), 1178 BaseDeclaration: s.baseDecl, 1179 } 1180 c.Check(cand.Check(), ErrorMatches, "connection not allowed.*") 1181 1182 // slot-side declaration, wrong snap-id 1183 cand = policy.ConnectCandidate{ 1184 Plug: interfaces.NewConnectedPlug(s.plugSnap.Plugs["precise-slot-snap-id"], nil, nil), 1185 PlugSnapDeclaration: s.plugDecl, 1186 Slot: interfaces.NewConnectedSlot(s.randomSnap.Slots["precise-slot-snap-id"], nil, nil), 1187 SlotSnapDeclaration: s.randomDecl, 1188 BaseDeclaration: s.baseDecl, 1189 } 1190 c.Check(cand.Check(), ErrorMatches, "connection not allowed.*") 1191 1192 // right snap-id 1193 cand = policy.ConnectCandidate{ 1194 Plug: interfaces.NewConnectedPlug(s.plugSnap.Plugs["precise-slot-snap-id"], nil, nil), 1195 PlugSnapDeclaration: s.plugDecl, 1196 Slot: interfaces.NewConnectedSlot(s.slotSnap.Slots["precise-slot-snap-id"], nil, nil), 1197 SlotSnapDeclaration: s.slotDecl, 1198 BaseDeclaration: s.baseDecl, 1199 } 1200 c.Check(cand.Check(), IsNil) 1201 } 1202 1203 func (s *policySuite) TestPlugPublisherIDCheckConnection(c *C) { 1204 // no plug-side declaration 1205 cand := policy.ConnectCandidate{ 1206 Plug: interfaces.NewConnectedPlug(s.randomSnap.Plugs["checked-plug-publisher-id"], nil, nil), 1207 Slot: interfaces.NewConnectedSlot(s.slotSnap.Slots["checked-plug-publisher-id"], nil, nil), 1208 SlotSnapDeclaration: s.slotDecl, 1209 BaseDeclaration: s.baseDecl, 1210 } 1211 c.Check(cand.Check(), ErrorMatches, "connection not allowed.*") 1212 1213 // plug-side declaration, wrong publisher-id 1214 cand = policy.ConnectCandidate{ 1215 Plug: interfaces.NewConnectedPlug(s.randomSnap.Plugs["checked-plug-publisher-id"], nil, nil), 1216 PlugSnapDeclaration: s.randomDecl, 1217 Slot: interfaces.NewConnectedSlot(s.slotSnap.Slots["checked-plug-publisher-id"], nil, nil), 1218 SlotSnapDeclaration: s.slotDecl, 1219 BaseDeclaration: s.baseDecl, 1220 } 1221 c.Check(cand.Check(), ErrorMatches, "connection not allowed.*") 1222 1223 // right publisher-id 1224 cand = policy.ConnectCandidate{ 1225 Plug: interfaces.NewConnectedPlug(s.plugSnap.Plugs["checked-plug-publisher-id"], nil, nil), 1226 PlugSnapDeclaration: s.plugDecl, 1227 Slot: interfaces.NewConnectedSlot(s.slotSnap.Slots["checked-plug-publisher-id"], nil, nil), 1228 SlotSnapDeclaration: s.slotDecl, 1229 BaseDeclaration: s.baseDecl, 1230 } 1231 c.Check(cand.Check(), IsNil) 1232 } 1233 1234 func (s *policySuite) TestSlotPublisherIDCheckConnection(c *C) { 1235 // no slot-side declaration 1236 cand := policy.ConnectCandidate{ 1237 Plug: interfaces.NewConnectedPlug(s.plugSnap.Plugs["checked-slot-publisher-id"], nil, nil), 1238 PlugSnapDeclaration: s.plugDecl, 1239 Slot: interfaces.NewConnectedSlot(s.randomSnap.Slots["checked-slot-publisher-id"], nil, nil), 1240 BaseDeclaration: s.baseDecl, 1241 } 1242 c.Check(cand.Check(), ErrorMatches, "connection not allowed.*") 1243 1244 // slot-side declaration, wrong publisher-id 1245 cand = policy.ConnectCandidate{ 1246 Plug: interfaces.NewConnectedPlug(s.plugSnap.Plugs["checked-slot-publisher-id"], nil, nil), 1247 PlugSnapDeclaration: s.plugDecl, 1248 Slot: interfaces.NewConnectedSlot(s.randomSnap.Slots["checked-slot-publisher-id"], nil, nil), 1249 SlotSnapDeclaration: s.randomDecl, 1250 BaseDeclaration: s.baseDecl, 1251 } 1252 c.Check(cand.Check(), ErrorMatches, "connection not allowed.*") 1253 1254 // right publisher-id 1255 cand = policy.ConnectCandidate{ 1256 Plug: interfaces.NewConnectedPlug(s.plugSnap.Plugs["checked-slot-publisher-id"], nil, nil), 1257 PlugSnapDeclaration: s.plugDecl, 1258 Slot: interfaces.NewConnectedSlot(s.slotSnap.Slots["checked-slot-publisher-id"], nil, nil), 1259 SlotSnapDeclaration: s.slotDecl, 1260 BaseDeclaration: s.baseDecl, 1261 } 1262 c.Check(cand.Check(), IsNil) 1263 } 1264 1265 func (s *policySuite) TestDollarPlugPublisherIDCheckConnection(c *C) { 1266 // no known publishers 1267 cand := policy.ConnectCandidate{ 1268 Plug: interfaces.NewConnectedPlug(s.plugSnap.Plugs["same-plug-publisher-id"], nil, nil), 1269 Slot: interfaces.NewConnectedSlot(s.randomSnap.Slots["same-plug-publisher-id"], nil, nil), 1270 BaseDeclaration: s.baseDecl, 1271 } 1272 c.Check(cand.Check(), ErrorMatches, "connection not allowed.*") 1273 1274 // no slot-side declaration 1275 cand = policy.ConnectCandidate{ 1276 Plug: interfaces.NewConnectedPlug(s.plugSnap.Plugs["same-plug-publisher-id"], nil, nil), 1277 PlugSnapDeclaration: s.plugDecl, 1278 Slot: interfaces.NewConnectedSlot(s.randomSnap.Slots["same-plug-publisher-id"], nil, nil), 1279 BaseDeclaration: s.baseDecl, 1280 } 1281 c.Check(cand.Check(), ErrorMatches, "connection not allowed.*") 1282 1283 // slot-side declaration, wrong publisher-id 1284 cand = policy.ConnectCandidate{ 1285 Plug: interfaces.NewConnectedPlug(s.plugSnap.Plugs["same-plug-publisher-id"], nil, nil), 1286 PlugSnapDeclaration: s.plugDecl, 1287 Slot: interfaces.NewConnectedSlot(s.randomSnap.Slots["same-plug-publisher-id"], nil, nil), 1288 SlotSnapDeclaration: s.randomDecl, 1289 BaseDeclaration: s.baseDecl, 1290 } 1291 c.Check(cand.Check(), ErrorMatches, "connection not allowed.*") 1292 1293 // slot publisher id == plug publisher id 1294 samePubSlotSnap := snaptest.MockInfo(c, ` 1295 name: same-pub-slot-snap 1296 version: 0 1297 slots: 1298 same-plug-publisher-id: 1299 `, nil) 1300 1301 a, err := asserts.Decode([]byte(`type: snap-declaration 1302 authority-id: canonical 1303 series: 16 1304 snap-name: same-pub-slot-snap 1305 snap-id: samepublslotsnapidididididididid 1306 publisher-id: plug-publisher 1307 timestamp: 2016-09-30T12:00:00Z 1308 sign-key-sha3-384: Jv8_JiHiIzJVcO9M55pPdqSDWUvuhfDIBJUS-3VW7F_idjix7Ffn5qMxB21ZQuij 1309 1310 AXNpZw==`)) 1311 c.Assert(err, IsNil) 1312 samePubSlotDecl := a.(*asserts.SnapDeclaration) 1313 1314 cand = policy.ConnectCandidate{ 1315 Plug: interfaces.NewConnectedPlug(s.plugSnap.Plugs["same-plug-publisher-id"], nil, nil), 1316 PlugSnapDeclaration: s.plugDecl, 1317 Slot: interfaces.NewConnectedSlot(samePubSlotSnap.Slots["same-plug-publisher-id"], nil, nil), 1318 SlotSnapDeclaration: samePubSlotDecl, 1319 BaseDeclaration: s.baseDecl, 1320 } 1321 c.Check(cand.Check(), IsNil) 1322 } 1323 1324 func (s *policySuite) TestDollarSlotPublisherIDCheckConnection(c *C) { 1325 // no known publishers 1326 cand := policy.ConnectCandidate{ 1327 Plug: interfaces.NewConnectedPlug(s.randomSnap.Plugs["same-slot-publisher-id"], nil, nil), 1328 Slot: interfaces.NewConnectedSlot(s.slotSnap.Slots["same-slot-publisher-id"], nil, nil), 1329 BaseDeclaration: s.baseDecl, 1330 } 1331 c.Check(cand.Check(), ErrorMatches, "connection not allowed.*") 1332 1333 // no plug-side declaration 1334 cand = policy.ConnectCandidate{ 1335 Plug: interfaces.NewConnectedPlug(s.randomSnap.Plugs["same-slot-publisher-id"], nil, nil), 1336 Slot: interfaces.NewConnectedSlot(s.slotSnap.Slots["same-slot-publisher-id"], nil, nil), 1337 SlotSnapDeclaration: s.slotDecl, 1338 BaseDeclaration: s.baseDecl, 1339 } 1340 c.Check(cand.Check(), ErrorMatches, "connection not allowed.*") 1341 1342 // plug-side declaration, wrong publisher-id 1343 cand = policy.ConnectCandidate{ 1344 Plug: interfaces.NewConnectedPlug(s.randomSnap.Plugs["same-slot-publisher-id"], nil, nil), 1345 PlugSnapDeclaration: s.randomDecl, 1346 Slot: interfaces.NewConnectedSlot(s.slotSnap.Slots["same-slot-publisher-id"], nil, nil), 1347 SlotSnapDeclaration: s.slotDecl, 1348 BaseDeclaration: s.baseDecl, 1349 } 1350 c.Check(cand.Check(), ErrorMatches, "connection not allowed.*") 1351 1352 // plug publisher id == slot publisher id 1353 samePubPlugSnap := snaptest.MockInfo(c, ` 1354 name: same-pub-plug-snap 1355 version: 0 1356 plugs: 1357 same-slot-publisher-id: 1358 `, nil) 1359 1360 a, err := asserts.Decode([]byte(`type: snap-declaration 1361 authority-id: canonical 1362 series: 16 1363 snap-name: same-pub-plug-snap 1364 snap-id: samepublplugsnapidididididididid 1365 publisher-id: slot-publisher 1366 timestamp: 2016-09-30T12:00:00Z 1367 sign-key-sha3-384: Jv8_JiHiIzJVcO9M55pPdqSDWUvuhfDIBJUS-3VW7F_idjix7Ffn5qMxB21ZQuij 1368 1369 AXNpZw==`)) 1370 c.Assert(err, IsNil) 1371 samePubPlugDecl := a.(*asserts.SnapDeclaration) 1372 1373 cand = policy.ConnectCandidate{ 1374 Plug: interfaces.NewConnectedPlug(samePubPlugSnap.Plugs["same-slot-publisher-id"], nil, nil), 1375 PlugSnapDeclaration: samePubPlugDecl, 1376 Slot: interfaces.NewConnectedSlot(s.slotSnap.Slots["same-slot-publisher-id"], nil, nil), 1377 SlotSnapDeclaration: s.slotDecl, 1378 BaseDeclaration: s.baseDecl, 1379 } 1380 c.Check(cand.Check(), IsNil) 1381 } 1382 1383 func (s *policySuite) TestBaselineDefaultIsAllowInstallation(c *C) { 1384 installSnap := snaptest.MockInfo(c, ` 1385 name: install-slot-snap 1386 version: 0 1387 slots: 1388 random1: 1389 plugs: 1390 random2: 1391 `, nil) 1392 1393 cand := policy.InstallCandidate{ 1394 Snap: installSnap, 1395 BaseDeclaration: s.baseDecl, 1396 } 1397 1398 c.Check(cand.Check(), IsNil) 1399 } 1400 1401 func (s *policySuite) TestBaseDeclAllowDenyInstallation(c *C) { 1402 1403 tests := []struct { 1404 installYaml string 1405 expected string // "" => no error 1406 }{ 1407 {`name: install-snap 1408 version: 0 1409 slots: 1410 innocuous: 1411 install-slot-coreonly: 1412 `, `installation not allowed by "install-slot-coreonly" slot rule of interface "install-slot-coreonly"`}, 1413 {`name: install-snap 1414 version: 0 1415 slots: 1416 install-slot-attr-ok: 1417 attr: ok 1418 `, ""}, 1419 {`name: install-snap 1420 version: 0 1421 slots: 1422 install-slot-attr-deny: 1423 trust: trusted 1424 `, `installation denied by "install-slot-attr-deny" slot rule of interface "install-slot-attr-deny"`}, 1425 {`name: install-snap 1426 version: 0 1427 plugs: 1428 install-plug-attr-ok: 1429 attr: ok 1430 `, ""}, 1431 {`name: install-snap 1432 version: 0 1433 plugs: 1434 install-plug-attr-ok: 1435 attr: not-ok 1436 `, `installation not allowed by "install-plug-attr-ok" plug rule of interface "install-plug-attr-ok"`}, 1437 {`name: install-snap 1438 version: 0 1439 plugs: 1440 install-plug-gadget-only: 1441 `, `installation not allowed by "install-plug-gadget-only" plug rule of interface "install-plug-gadget-only"`}, 1442 {`name: install-gadget 1443 version: 0 1444 type: gadget 1445 plugs: 1446 install-plug-gadget-only: 1447 `, ""}, 1448 {`name: install-gadget 1449 version: 0 1450 type: gadget 1451 plugs: 1452 install-plug-or: 1453 p: P2`, `installation denied by "install-plug-or" plug rule.*`}, 1454 {`name: install-snap 1455 version: 0 1456 plugs: 1457 install-plug-or: 1458 p: P1`, `installation denied by "install-plug-or" plug rule.*`}, 1459 {`name: install-snap 1460 version: 0 1461 plugs: 1462 install-plug-or: 1463 p: P3`, ""}, 1464 {`name: install-gadget 1465 version: 0 1466 type: gadget 1467 slots: 1468 install-slot-or: 1469 p: P2`, `installation denied by "install-slot-or" slot rule.*`}, 1470 {`name: install-snap 1471 version: 0 1472 slots: 1473 install-slot-or: 1474 p: P1`, `installation denied by "install-slot-or" slot rule.*`}, 1475 {`name: install-snap 1476 version: 0 1477 slots: 1478 install-slot-or: 1479 p: P3`, ""}, 1480 } 1481 1482 for _, t := range tests { 1483 installSnap := snaptest.MockInfo(c, t.installYaml, nil) 1484 1485 cand := policy.InstallCandidate{ 1486 Snap: installSnap, 1487 BaseDeclaration: s.baseDecl, 1488 } 1489 1490 err := cand.Check() 1491 if t.expected == "" { 1492 c.Check(err, IsNil) 1493 } else { 1494 c.Check(err, ErrorMatches, t.expected) 1495 } 1496 } 1497 } 1498 1499 func (s *policySuite) TestSnapDeclAllowDenyInstallation(c *C) { 1500 1501 tests := []struct { 1502 installYaml string 1503 plugsSlots string 1504 expected string // "" => no error 1505 }{ 1506 {`name: install-snap 1507 version: 0 1508 slots: 1509 install-slot-base-allow-snap-deny: 1510 have: yes # bool 1511 `, `slots: 1512 install-slot-base-allow-snap-deny: 1513 deny-installation: 1514 slot-attributes: 1515 have: true 1516 `, `installation denied by "install-slot-base-allow-snap-deny" slot rule of interface "install-slot-base-allow-snap-deny" for "install-snap" snap`}, 1517 {`name: install-snap 1518 version: 0 1519 slots: 1520 install-slot-base-allow-snap-not-allow: 1521 have: yes # bool 1522 `, `slots: 1523 install-slot-base-allow-snap-not-allow: 1524 allow-installation: 1525 slot-attributes: 1526 have: false 1527 `, `installation not allowed by "install-slot-base-allow-snap-not-allow" slot rule of interface "install-slot-base-allow-snap-not-allow" for "install-snap" snap`}, 1528 {`name: install-snap 1529 version: 0 1530 slots: 1531 install-slot-base-deny-snap-allow: 1532 have: yes 1533 `, `slots: 1534 install-slot-base-deny-snap-allow: 1535 allow-installation: true 1536 `, ""}, 1537 {`name: install-snap 1538 version: 0 1539 plugs: 1540 install-plug-base-allow-snap-deny: 1541 attr: give-me 1542 `, `plugs: 1543 install-plug-base-allow-snap-deny: 1544 deny-installation: 1545 plug-attributes: 1546 attr: .* 1547 `, `installation denied by "install-plug-base-allow-snap-deny" plug rule of interface "install-plug-base-allow-snap-deny" for "install-snap" snap`}, 1548 {`name: install-snap 1549 version: 0 1550 plugs: 1551 install-plug-base-allow-snap-not-allow: 1552 attr: give-me 1553 `, `plugs: 1554 install-plug-base-allow-snap-not-allow: 1555 allow-installation: 1556 plug-attributes: 1557 attr: minimal 1558 `, `installation not allowed by "install-plug-base-allow-snap-not-allow" plug rule of interface "install-plug-base-allow-snap-not-allow" for "install-snap" snap`}, 1559 {`name: install-snap 1560 version: 0 1561 plugs: 1562 install-plug-base-deny-snap-allow: 1563 attr: attrvalue 1564 `, `plugs: 1565 install-plug-base-deny-snap-allow: 1566 allow-installation: 1567 plug-attributes: 1568 attr: attrvalue 1569 `, ""}, 1570 } 1571 1572 for _, t := range tests { 1573 installSnap := snaptest.MockInfo(c, t.installYaml, nil) 1574 1575 a, err := asserts.Decode([]byte(strings.Replace(`type: snap-declaration 1576 authority-id: canonical 1577 series: 16 1578 snap-name: install-snap 1579 snap-id: installsnap6idididididididididid 1580 publisher-id: publisher 1581 @plugsSlots@ 1582 timestamp: 2016-09-30T12:00:00Z 1583 sign-key-sha3-384: Jv8_JiHiIzJVcO9M55pPdqSDWUvuhfDIBJUS-3VW7F_idjix7Ffn5qMxB21ZQuij 1584 1585 AXNpZw==`, "@plugsSlots@", strings.TrimSpace(t.plugsSlots), 1))) 1586 c.Assert(err, IsNil) 1587 snapDecl := a.(*asserts.SnapDeclaration) 1588 1589 cand := policy.InstallCandidate{ 1590 Snap: installSnap, 1591 SnapDeclaration: snapDecl, 1592 BaseDeclaration: s.baseDecl, 1593 } 1594 1595 err = cand.Check() 1596 if t.expected == "" { 1597 c.Check(err, IsNil) 1598 } else { 1599 c.Check(err, ErrorMatches, t.expected) 1600 } 1601 } 1602 } 1603 1604 func (s *policySuite) TestBaseDeclAllowDenyInstallationMinimalCheck(c *C) { 1605 tests := []struct { 1606 installYaml string 1607 expected string // "" => no error 1608 }{ 1609 {`name: install-snap 1610 version: 0 1611 slots: 1612 innocuous: 1613 install-slot-coreonly: 1614 `, `installation not allowed by "install-slot-coreonly" slot rule of interface "install-slot-coreonly"`}, 1615 {`name: install-gadget 1616 version: 0 1617 type: gadget 1618 slots: 1619 install-slot-or: 1620 `, `installation denied by "install-slot-or" slot rule.*`}, 1621 {`name: install-snap 1622 version: 0 1623 slots: 1624 install-slot-or: 1625 `, ""}, 1626 {`name: install-snap 1627 version: 0 1628 plugs: 1629 install-plug-gadget-only: 1630 `, ``}, // plug is not validated with minimal installation check 1631 } 1632 1633 for _, t := range tests { 1634 installSnap := snaptest.MockInfo(c, t.installYaml, nil) 1635 1636 cand := policy.InstallCandidateMinimalCheck{ 1637 Snap: installSnap, 1638 BaseDeclaration: s.baseDecl, 1639 } 1640 1641 err := cand.Check() 1642 if t.expected == "" { 1643 c.Check(err, IsNil) 1644 } else { 1645 c.Check(err, ErrorMatches, t.expected) 1646 } 1647 } 1648 } 1649 1650 func (s *policySuite) TestOnClassicMinimalInstallationCheck(c *C) { 1651 r1 := release.MockOnClassic(false) 1652 defer r1() 1653 r2 := release.MockReleaseInfo(&release.ReleaseInfo) 1654 defer r2() 1655 1656 tests := []struct { 1657 distro string // "" => not classic 1658 installYaml string 1659 err string // "" => no error 1660 }{ 1661 {"", `name: install-snap 1662 version: 0 1663 slots: 1664 install-slot-on-classic-distros:`, `installation not allowed by "install-slot-on-classic-distros" slot rule.*`}, 1665 {"debian", `name: install-snap 1666 version: 0 1667 slots: 1668 install-slot-on-classic-distros:`, ""}, 1669 {"", `name: install-snap 1670 version: 0 1671 plugs: 1672 install-plug-on-classic-distros:`, ""}, // plug is not validated with minimal installation check 1673 {"debian", `name: install-snap 1674 version: 0 1675 plugs: 1676 install-plug-on-classic-distros:`, ""}, 1677 } 1678 1679 for _, t := range tests { 1680 if t.distro == "" { 1681 release.OnClassic = false 1682 } else { 1683 release.OnClassic = true 1684 release.ReleaseInfo = release.OS{ 1685 ID: t.distro, 1686 } 1687 } 1688 1689 installSnap := snaptest.MockInfo(c, t.installYaml, nil) 1690 1691 cand := policy.InstallCandidateMinimalCheck{ 1692 Snap: installSnap, 1693 BaseDeclaration: s.baseDecl, 1694 } 1695 err := cand.Check() 1696 if t.err == "" { 1697 c.Check(err, IsNil) 1698 } else { 1699 c.Check(err, ErrorMatches, t.err) 1700 } 1701 } 1702 } 1703 1704 func (s *policySuite) TestPlugOnClassicCheckConnection(c *C) { 1705 r1 := release.MockOnClassic(false) 1706 defer r1() 1707 r2 := release.MockReleaseInfo(&release.ReleaseInfo) 1708 defer r2() 1709 1710 tests := []struct { 1711 distro string // "" => not classic 1712 iface string 1713 err string // "" => no error 1714 }{ 1715 {"ubuntu", "plug-on-classic-true", ""}, 1716 {"", "plug-on-classic-true", `connection not allowed by plug rule of interface "plug-on-classic-true"`}, 1717 {"", "plug-on-classic-false", ""}, 1718 {"ubuntu", "plug-on-classic-false", "connection not allowed.*"}, 1719 {"ubuntu", "plug-on-classic-distros", ""}, 1720 {"debian", "plug-on-classic-distros", ""}, 1721 {"", "plug-on-classic-distros", "connection not allowed.*"}, 1722 {"other", "plug-on-classic-distros", "connection not allowed.*"}, 1723 } 1724 1725 for _, t := range tests { 1726 if t.distro == "" { 1727 release.OnClassic = false 1728 } else { 1729 release.OnClassic = true 1730 release.ReleaseInfo = release.OS{ 1731 ID: t.distro, 1732 } 1733 } 1734 cand := policy.ConnectCandidate{ 1735 Plug: interfaces.NewConnectedPlug(s.plugSnap.Plugs[t.iface], nil, nil), 1736 Slot: interfaces.NewConnectedSlot(s.slotSnap.Slots[t.iface], nil, nil), 1737 BaseDeclaration: s.baseDecl, 1738 } 1739 err := cand.Check() 1740 if t.err == "" { 1741 c.Check(err, IsNil) 1742 } else { 1743 c.Check(err, ErrorMatches, t.err) 1744 } 1745 } 1746 } 1747 1748 func (s *policySuite) TestSlotOnClassicCheckConnection(c *C) { 1749 r1 := release.MockOnClassic(false) 1750 defer r1() 1751 r2 := release.MockReleaseInfo(&release.ReleaseInfo) 1752 defer r2() 1753 1754 tests := []struct { 1755 distro string // "" => not classic 1756 iface string 1757 err string // "" => no error 1758 }{ 1759 {"ubuntu", "slot-on-classic-true", ""}, 1760 {"", "slot-on-classic-true", `connection not allowed by slot rule of interface "slot-on-classic-true"`}, 1761 {"", "slot-on-classic-false", ""}, 1762 {"ubuntu", "slot-on-classic-false", "connection not allowed.*"}, 1763 {"ubuntu", "slot-on-classic-distros", ""}, 1764 {"debian", "slot-on-classic-distros", ""}, 1765 {"", "slot-on-classic-distros", "connection not allowed.*"}, 1766 {"other", "slot-on-classic-distros", "connection not allowed.*"}, 1767 } 1768 1769 for _, t := range tests { 1770 if t.distro == "" { 1771 release.OnClassic = false 1772 } else { 1773 release.OnClassic = true 1774 release.ReleaseInfo = release.OS{ 1775 ID: t.distro, 1776 } 1777 } 1778 cand := policy.ConnectCandidate{ 1779 Plug: interfaces.NewConnectedPlug(s.plugSnap.Plugs[t.iface], nil, nil), 1780 Slot: interfaces.NewConnectedSlot(s.slotSnap.Slots[t.iface], nil, nil), 1781 BaseDeclaration: s.baseDecl, 1782 } 1783 err := cand.Check() 1784 if t.err == "" { 1785 c.Check(err, IsNil) 1786 } else { 1787 c.Check(err, ErrorMatches, t.err) 1788 } 1789 } 1790 } 1791 1792 func (s *policySuite) TestOnClassicInstallation(c *C) { 1793 r1 := release.MockOnClassic(false) 1794 defer r1() 1795 r2 := release.MockReleaseInfo(&release.ReleaseInfo) 1796 defer r2() 1797 1798 tests := []struct { 1799 distro string // "" => not classic 1800 installYaml string 1801 err string // "" => no error 1802 }{ 1803 {"", `name: install-snap 1804 version: 0 1805 slots: 1806 install-slot-on-classic-distros:`, `installation not allowed by "install-slot-on-classic-distros" slot rule.*`}, 1807 {"debian", `name: install-snap 1808 version: 0 1809 slots: 1810 install-slot-on-classic-distros:`, ""}, 1811 {"", `name: install-snap 1812 version: 0 1813 plugs: 1814 install-plug-on-classic-distros:`, `installation not allowed by "install-plug-on-classic-distros" plug rule.*`}, 1815 {"debian", `name: install-snap 1816 version: 0 1817 plugs: 1818 install-plug-on-classic-distros:`, ""}, 1819 } 1820 1821 for _, t := range tests { 1822 if t.distro == "" { 1823 release.OnClassic = false 1824 } else { 1825 release.OnClassic = true 1826 release.ReleaseInfo = release.OS{ 1827 ID: t.distro, 1828 } 1829 } 1830 1831 installSnap := snaptest.MockInfo(c, t.installYaml, nil) 1832 1833 cand := policy.InstallCandidate{ 1834 Snap: installSnap, 1835 BaseDeclaration: s.baseDecl, 1836 } 1837 err := cand.Check() 1838 if t.err == "" { 1839 c.Check(err, IsNil) 1840 } else { 1841 c.Check(err, ErrorMatches, t.err) 1842 } 1843 } 1844 } 1845 1846 var ( 1847 otherModel *asserts.Model 1848 myModel1 *asserts.Model 1849 myModel2 *asserts.Model 1850 myModel3 *asserts.Model 1851 1852 substore1 *asserts.Store 1853 ) 1854 1855 func init() { 1856 a, err := asserts.Decode([]byte(`type: model 1857 authority-id: other-brand 1858 series: 16 1859 brand-id: other-brand 1860 model: other-model 1861 classic: true 1862 gadget: gadget 1863 timestamp: 2018-09-12T12:00:00Z 1864 sign-key-sha3-384: Jv8_JiHiIzJVcO9M55pPdqSDWUvuhfDIBJUS-3VW7F_idjix7Ffn5qMxB21ZQuij 1865 1866 AXNpZw==`)) 1867 if err != nil { 1868 panic(err) 1869 } 1870 otherModel = a.(*asserts.Model) 1871 1872 a, err = asserts.Decode([]byte(`type: model 1873 authority-id: my-brand 1874 series: 16 1875 brand-id: my-brand 1876 model: my-model1 1877 store: store1 1878 architecture: armhf 1879 kernel: krnl 1880 gadget: gadget 1881 timestamp: 2018-09-12T12:00:00Z 1882 sign-key-sha3-384: Jv8_JiHiIzJVcO9M55pPdqSDWUvuhfDIBJUS-3VW7F_idjix7Ffn5qMxB21ZQuij 1883 1884 AXNpZw==`)) 1885 if err != nil { 1886 panic(err) 1887 } 1888 myModel1 = a.(*asserts.Model) 1889 1890 a, err = asserts.Decode([]byte(`type: model 1891 authority-id: my-brand-subbrand 1892 series: 16 1893 brand-id: my-brand-subbrand 1894 model: my-model2 1895 store: store2 1896 architecture: armhf 1897 kernel: krnl 1898 gadget: gadget 1899 timestamp: 2018-09-12T12:00:00Z 1900 sign-key-sha3-384: Jv8_JiHiIzJVcO9M55pPdqSDWUvuhfDIBJUS-3VW7F_idjix7Ffn5qMxB21ZQuij 1901 1902 AXNpZw==`)) 1903 if err != nil { 1904 panic(err) 1905 } 1906 myModel2 = a.(*asserts.Model) 1907 1908 a, err = asserts.Decode([]byte(`type: model 1909 authority-id: my-brand 1910 series: 16 1911 brand-id: my-brand 1912 model: my-model3 1913 store: substore1 1914 architecture: armhf 1915 kernel: krnl 1916 gadget: gadget 1917 timestamp: 2018-09-12T12:00:00Z 1918 sign-key-sha3-384: Jv8_JiHiIzJVcO9M55pPdqSDWUvuhfDIBJUS-3VW7F_idjix7Ffn5qMxB21ZQuij 1919 1920 AXNpZw==`)) 1921 if err != nil { 1922 panic(err) 1923 } 1924 myModel3 = a.(*asserts.Model) 1925 1926 a, err = asserts.Decode([]byte(`type: store 1927 store: substore1 1928 authority-id: canonical 1929 operator-id: canonical 1930 friendly-stores: 1931 - a-store 1932 - store1 1933 - store2 1934 timestamp: 2018-09-12T12:00:00Z 1935 sign-key-sha3-384: Jv8_JiHiIzJVcO9M55pPdqSDWUvuhfDIBJUS-3VW7F_idjix7Ffn5qMxB21ZQuij 1936 1937 AXNpZw==`)) 1938 if err != nil { 1939 panic(err) 1940 } 1941 substore1 = a.(*asserts.Store) 1942 } 1943 1944 func (s *policySuite) TestPlugDeviceScopeCheckAutoConnection(c *C) { 1945 tests := []struct { 1946 model *asserts.Model 1947 iface string 1948 err string // "" => no error 1949 }{ 1950 {nil, "auto-plug-on-store1", `auto-connection not allowed by plug rule of interface "auto-plug-on-store1" for "plug-snap" snap`}, 1951 {otherModel, "auto-plug-on-store1", `auto-connection not allowed by plug rule of interface "auto-plug-on-store1" for "plug-snap" snap`}, 1952 {myModel1, "auto-plug-on-store1", ""}, 1953 {myModel2, "auto-plug-on-store1", `auto-connection not allowed by plug rule of interface "auto-plug-on-store1" for "plug-snap" snap`}, 1954 {otherModel, "auto-plug-on-my-brand", `auto-connection not allowed by plug rule of interface "auto-plug-on-my-brand" for "plug-snap" snap`}, 1955 {myModel1, "auto-plug-on-my-brand", ""}, 1956 {myModel2, "auto-plug-on-my-brand", ""}, 1957 {otherModel, "auto-plug-on-my-model2", `auto-connection not allowed by plug rule of interface "auto-plug-on-my-model2" for "plug-snap" snap`}, 1958 {myModel1, "auto-plug-on-my-model2", `auto-connection not allowed by plug rule of interface "auto-plug-on-my-model2" for "plug-snap" snap`}, 1959 {myModel2, "auto-plug-on-my-model2", ""}, 1960 // on-store/on-brand/on-model are ANDed for consistency! 1961 {otherModel, "auto-plug-on-multi", `auto-connection not allowed by plug rule of interface "auto-plug-on-multi" for "plug-snap" snap`}, 1962 {myModel1, "auto-plug-on-multi", ""}, 1963 {myModel2, "auto-plug-on-multi", `auto-connection not allowed by plug rule of interface "auto-plug-on-multi" for "plug-snap" snap`}, 1964 } 1965 1966 for _, t := range tests { 1967 cand := policy.ConnectCandidate{ 1968 Plug: interfaces.NewConnectedPlug(s.plugSnap.Plugs[t.iface], nil, nil), 1969 Slot: interfaces.NewConnectedSlot(s.slotSnap.Slots[t.iface], nil, nil), 1970 PlugSnapDeclaration: s.plugDecl, 1971 SlotSnapDeclaration: s.slotDecl, 1972 1973 BaseDeclaration: s.baseDecl, 1974 1975 Model: t.model, 1976 } 1977 arity, err := cand.CheckAutoConnect() 1978 if t.err == "" { 1979 c.Check(err, IsNil) 1980 c.Check(arity.SlotsPerPlugAny(), Equals, false) 1981 } else { 1982 c.Check(err, ErrorMatches, t.err) 1983 } 1984 } 1985 } 1986 1987 func (s *policySuite) TestPlugDeviceScopeFriendlyStoreCheckAutoConnection(c *C) { 1988 tests := []struct { 1989 model *asserts.Model 1990 store *asserts.Store 1991 iface string 1992 err string // "" => no error 1993 }{ 1994 {nil, nil, "auto-plug-on-store1", `auto-connection not allowed by plug rule of interface "auto-plug-on-store1" for "plug-snap" snap`}, 1995 {myModel3, nil, "auto-plug-on-store1", `auto-connection not allowed by plug rule of interface "auto-plug-on-store1" for "plug-snap" snap`}, 1996 {myModel3, substore1, "auto-plug-on-store1", ""}, 1997 {myModel2, substore1, "auto-plug-on-store1", `auto-connection not allowed by plug rule of interface "auto-plug-on-store1" for "plug-snap" snap`}, 1998 } 1999 2000 for _, t := range tests { 2001 cand := policy.ConnectCandidate{ 2002 Plug: interfaces.NewConnectedPlug(s.plugSnap.Plugs[t.iface], nil, nil), 2003 Slot: interfaces.NewConnectedSlot(s.slotSnap.Slots[t.iface], nil, nil), 2004 PlugSnapDeclaration: s.plugDecl, 2005 SlotSnapDeclaration: s.slotDecl, 2006 2007 BaseDeclaration: s.baseDecl, 2008 2009 Model: t.model, 2010 Store: t.store, 2011 } 2012 arity, err := cand.CheckAutoConnect() 2013 if t.err == "" { 2014 c.Check(err, IsNil) 2015 c.Check(arity.SlotsPerPlugAny(), Equals, false) 2016 } else { 2017 c.Check(err, ErrorMatches, t.err) 2018 } 2019 } 2020 } 2021 2022 func (s *policySuite) TestSlotDeviceScopeCheckAutoConnection(c *C) { 2023 tests := []struct { 2024 model *asserts.Model 2025 iface string 2026 err string // "" => no error 2027 }{ 2028 {nil, "auto-slot-on-store1", `auto-connection not allowed by slot rule of interface "auto-slot-on-store1" for "slot-snap" snap`}, 2029 {otherModel, "auto-slot-on-store1", `auto-connection not allowed by slot rule of interface "auto-slot-on-store1" for "slot-snap" snap`}, 2030 {myModel1, "auto-slot-on-store1", ""}, 2031 {myModel2, "auto-slot-on-store1", `auto-connection not allowed by slot rule of interface "auto-slot-on-store1" for "slot-snap" snap`}, 2032 {otherModel, "auto-slot-on-my-brand", `auto-connection not allowed by slot rule of interface "auto-slot-on-my-brand" for "slot-snap" snap`}, 2033 {myModel1, "auto-slot-on-my-brand", ""}, 2034 {myModel2, "auto-slot-on-my-brand", ""}, 2035 {otherModel, "auto-slot-on-my-model2", `auto-connection not allowed by slot rule of interface "auto-slot-on-my-model2" for "slot-snap" snap`}, 2036 {myModel1, "auto-slot-on-my-model2", `auto-connection not allowed by slot rule of interface "auto-slot-on-my-model2" for "slot-snap" snap`}, 2037 {myModel2, "auto-slot-on-my-model2", ""}, 2038 // on-store/on-brand/on-model are ANDed for consistency! 2039 {otherModel, "auto-slot-on-multi", `auto-connection not allowed by slot rule of interface "auto-slot-on-multi" for "slot-snap" snap`}, 2040 {myModel1, "auto-slot-on-multi", ""}, 2041 {myModel2, "auto-slot-on-multi", `auto-connection not allowed by slot rule of interface "auto-slot-on-multi" for "slot-snap" snap`}, 2042 } 2043 2044 for _, t := range tests { 2045 cand := policy.ConnectCandidate{ 2046 Plug: interfaces.NewConnectedPlug(s.plugSnap.Plugs[t.iface], nil, nil), 2047 Slot: interfaces.NewConnectedSlot(s.slotSnap.Slots[t.iface], nil, nil), 2048 PlugSnapDeclaration: s.plugDecl, 2049 SlotSnapDeclaration: s.slotDecl, 2050 2051 BaseDeclaration: s.baseDecl, 2052 2053 Model: t.model, 2054 } 2055 arity, err := cand.CheckAutoConnect() 2056 if t.err == "" { 2057 c.Check(err, IsNil) 2058 c.Check(arity.SlotsPerPlugAny(), Equals, false) 2059 } else { 2060 c.Check(err, ErrorMatches, t.err) 2061 } 2062 } 2063 } 2064 2065 func (s *policySuite) TestSlotDeviceScopeFriendlyStoreCheckAutoConnection(c *C) { 2066 tests := []struct { 2067 model *asserts.Model 2068 store *asserts.Store 2069 iface string 2070 err string // "" => no error 2071 }{ 2072 {nil, nil, "auto-slot-on-store1", `auto-connection not allowed by slot rule of interface "auto-slot-on-store1" for "slot-snap" snap`}, 2073 {myModel3, nil, "auto-slot-on-store1", `auto-connection not allowed by slot rule of interface "auto-slot-on-store1" for "slot-snap" snap`}, 2074 {myModel3, substore1, "auto-slot-on-store1", ""}, 2075 {myModel2, substore1, "auto-slot-on-store1", `auto-connection not allowed by slot rule of interface "auto-slot-on-store1" for "slot-snap" snap`}, 2076 } 2077 2078 for _, t := range tests { 2079 cand := policy.ConnectCandidate{ 2080 Plug: interfaces.NewConnectedPlug(s.plugSnap.Plugs[t.iface], nil, nil), 2081 Slot: interfaces.NewConnectedSlot(s.slotSnap.Slots[t.iface], nil, nil), 2082 PlugSnapDeclaration: s.plugDecl, 2083 SlotSnapDeclaration: s.slotDecl, 2084 2085 BaseDeclaration: s.baseDecl, 2086 2087 Model: t.model, 2088 Store: t.store, 2089 } 2090 arity, err := cand.CheckAutoConnect() 2091 if t.err == "" { 2092 c.Check(err, IsNil) 2093 c.Check(arity.SlotsPerPlugAny(), Equals, false) 2094 } else { 2095 c.Check(err, ErrorMatches, t.err) 2096 } 2097 } 2098 } 2099 2100 func (s *policySuite) TestDeviceScopeInstallation(c *C) { 2101 const plugSnap = `name: install-snap 2102 version: 0 2103 plugs: 2104 install-plug-device-scope:` 2105 2106 const slotSnap = `name: install-snap 2107 version: 0 2108 slots: 2109 install-slot-device-scope:` 2110 2111 const plugOnStore1 = `plugs: 2112 install-plug-device-scope: 2113 allow-installation: 2114 on-store: 2115 - store1 2116 ` 2117 const plugOnMulti = `plugs: 2118 install-plug-device-scope: 2119 allow-installation: 2120 on-brand: 2121 - my-brand 2122 - my-brand-subbrand 2123 on-store: 2124 - store1 2125 - other-store 2126 on-model: 2127 - my-brand/my-model1 2128 - my-brand-subbrand/my-model2 2129 ` 2130 const slotOnStore2 = `slots: 2131 install-slot-device-scope: 2132 allow-installation: 2133 on-store: 2134 - store2 2135 ` 2136 2137 tests := []struct { 2138 model *asserts.Model 2139 store *asserts.Store 2140 installYaml string 2141 plugsSlots string 2142 err string // "" => no error 2143 }{ 2144 {nil, nil, plugSnap, plugOnStore1, `installation not allowed by "install-plug-device-scope" plug rule of interface "install-plug-device-scope" for "install-snap" snap`}, 2145 {otherModel, nil, plugSnap, plugOnStore1, `installation not allowed by "install-plug-device-scope" plug rule of interface "install-plug-device-scope" for "install-snap" snap`}, 2146 {myModel1, nil, plugSnap, plugOnStore1, ""}, 2147 {myModel2, nil, plugSnap, plugOnStore1, `installation not allowed by "install-plug-device-scope" plug rule of interface "install-plug-device-scope" for "install-snap" snap`}, 2148 {otherModel, nil, plugSnap, plugOnMulti, `installation not allowed by "install-plug-device-scope" plug rule of interface "install-plug-device-scope" for "install-snap" snap`}, 2149 {myModel1, nil, plugSnap, plugOnMulti, ""}, 2150 {myModel2, nil, plugSnap, plugOnMulti, `installation not allowed by "install-plug-device-scope" plug rule of interface "install-plug-device-scope" for "install-snap" snap`}, 2151 {otherModel, nil, slotSnap, slotOnStore2, `installation not allowed by "install-slot-device-scope" slot rule of interface "install-slot-device-scope" for "install-snap" snap`}, 2152 {myModel1, nil, slotSnap, slotOnStore2, `installation not allowed by "install-slot-device-scope" slot rule of interface "install-slot-device-scope" for "install-snap" snap`}, 2153 {myModel2, nil, slotSnap, slotOnStore2, ""}, 2154 // friendly-stores 2155 {myModel3, nil, plugSnap, plugOnStore1, `installation not allowed by "install-plug-device-scope" plug rule of interface "install-plug-device-scope" for "install-snap" snap`}, 2156 {myModel3, substore1, plugSnap, plugOnStore1, ""}, 2157 {myModel2, substore1, plugSnap, plugOnStore1, `installation not allowed by "install-plug-device-scope" plug rule of interface "install-plug-device-scope" for "install-snap" snap`}, 2158 {myModel3, nil, slotSnap, slotOnStore2, `installation not allowed by "install-slot-device-scope" slot rule of interface "install-slot-device-scope" for \"install-snap\" snap`}, 2159 {myModel3, substore1, slotSnap, slotOnStore2, ""}, 2160 {myModel2, substore1, slotSnap, slotOnStore2, `installation not allowed by "install-slot-device-scope" slot rule of interface "install-slot-device-scope" for \"install-snap\" snap`}, 2161 } 2162 2163 for _, t := range tests { 2164 installSnap := snaptest.MockInfo(c, t.installYaml, nil) 2165 2166 a, err := asserts.Decode([]byte(strings.Replace(`type: snap-declaration 2167 authority-id: canonical 2168 series: 16 2169 snap-name: install-snap 2170 snap-id: installsnap6idididididididididid 2171 publisher-id: publisher 2172 @plugsSlots@ 2173 timestamp: 2016-09-30T12:00:00Z 2174 sign-key-sha3-384: Jv8_JiHiIzJVcO9M55pPdqSDWUvuhfDIBJUS-3VW7F_idjix7Ffn5qMxB21ZQuij 2175 2176 AXNpZw==`, "@plugsSlots@", strings.TrimSpace(t.plugsSlots), 1))) 2177 c.Assert(err, IsNil) 2178 snapDecl := a.(*asserts.SnapDeclaration) 2179 2180 cand := policy.InstallCandidate{ 2181 Snap: installSnap, 2182 SnapDeclaration: snapDecl, 2183 BaseDeclaration: s.baseDecl, 2184 Model: t.model, 2185 Store: t.store, 2186 } 2187 err = cand.Check() 2188 if t.err == "" { 2189 c.Check(err, IsNil) 2190 } else { 2191 c.Check(err, ErrorMatches, t.err) 2192 } 2193 } 2194 } 2195 2196 func (s *policySuite) TestSlotDollarSlotAttrConnection(c *C) { 2197 // no corresponding attr 2198 cand := policy.ConnectCandidate{ 2199 Plug: interfaces.NewConnectedPlug(s.randomSnap.Plugs["slot-slot-attr"], nil, nil), 2200 Slot: interfaces.NewConnectedSlot(s.slotSnap.Slots["slot-slot-attr"], nil, nil), 2201 BaseDeclaration: s.baseDecl, 2202 } 2203 c.Check(cand.Check(), ErrorMatches, "connection not allowed.*") 2204 2205 // different attr values 2206 cand = policy.ConnectCandidate{ 2207 Plug: interfaces.NewConnectedPlug(s.plugSnap.Plugs["slot-slot-attr-mismatch"], nil, nil), 2208 Slot: interfaces.NewConnectedSlot(s.slotSnap.Slots["slot-slot-attr"], nil, nil), 2209 BaseDeclaration: s.baseDecl, 2210 } 2211 c.Check(cand.Check(), ErrorMatches, "connection not allowed.*") 2212 2213 // plug attr == slot attr 2214 cand = policy.ConnectCandidate{ 2215 Plug: interfaces.NewConnectedPlug(s.plugSnap.Plugs["slot-slot-attr-match"], nil, nil), 2216 Slot: interfaces.NewConnectedSlot(s.slotSnap.Slots["slot-slot-attr"], nil, nil), 2217 BaseDeclaration: s.baseDecl, 2218 } 2219 c.Check(cand.Check(), IsNil) 2220 } 2221 2222 func (s *policySuite) TestSlotDollarPlugAttrConnection(c *C) { 2223 // different attr values 2224 cand := policy.ConnectCandidate{ 2225 Plug: interfaces.NewConnectedPlug(s.plugSnap.Plugs["slot-plug-attr-mismatch"], nil, nil), 2226 Slot: interfaces.NewConnectedSlot(s.slotSnap.Slots["slot-plug-attr"], nil, nil), 2227 BaseDeclaration: s.baseDecl, 2228 } 2229 c.Check(cand.Check(), ErrorMatches, "connection not allowed.*") 2230 2231 // plug attr == slot attr 2232 cand = policy.ConnectCandidate{ 2233 Plug: interfaces.NewConnectedPlug(s.plugSnap.Plugs["slot-plug-attr-match"], nil, nil), 2234 Slot: interfaces.NewConnectedSlot(s.slotSnap.Slots["slot-plug-attr"], nil, nil), 2235 BaseDeclaration: s.baseDecl, 2236 } 2237 c.Check(cand.Check(), IsNil) 2238 } 2239 2240 func (s *policySuite) TestPlugDollarPlugAttrConnection(c *C) { 2241 // different attr values 2242 cand := policy.ConnectCandidate{ 2243 Plug: interfaces.NewConnectedPlug(s.plugSnap.Plugs["plug-plug-attr"], nil, nil), 2244 Slot: interfaces.NewConnectedSlot(s.slotSnap.Slots["plug-plug-attr-mismatch"], nil, nil), 2245 BaseDeclaration: s.baseDecl, 2246 } 2247 c.Check(cand.Check(), ErrorMatches, "connection not allowed.*") 2248 2249 // plug attr == slot attr 2250 cand = policy.ConnectCandidate{ 2251 Plug: interfaces.NewConnectedPlug(s.plugSnap.Plugs["plug-plug-attr"], nil, nil), 2252 Slot: interfaces.NewConnectedSlot(s.slotSnap.Slots["plug-plug-attr-match"], nil, nil), 2253 BaseDeclaration: s.baseDecl, 2254 } 2255 c.Check(cand.Check(), IsNil) 2256 } 2257 2258 func (s *policySuite) TestPlugDollarSlotAttrConnection(c *C) { 2259 // different attr values 2260 cand := policy.ConnectCandidate{ 2261 Plug: interfaces.NewConnectedPlug(s.plugSnap.Plugs["plug-slot-attr"], nil, nil), 2262 Slot: interfaces.NewConnectedSlot(s.slotSnap.Slots["plug-slot-attr-mismatch"], nil, nil), 2263 BaseDeclaration: s.baseDecl, 2264 } 2265 c.Check(cand.Check(), ErrorMatches, "connection not allowed.*") 2266 2267 // plug attr == slot attr 2268 cand = policy.ConnectCandidate{ 2269 Plug: interfaces.NewConnectedPlug(s.plugSnap.Plugs["plug-slot-attr"], nil, nil), 2270 Slot: interfaces.NewConnectedSlot(s.slotSnap.Slots["plug-slot-attr-match"], nil, nil), 2271 BaseDeclaration: s.baseDecl, 2272 } 2273 c.Check(cand.Check(), IsNil) 2274 } 2275 2276 func (s *policySuite) TestDollarMissingConnection(c *C) { 2277 // not missing 2278 cand := policy.ConnectCandidate{ 2279 Plug: interfaces.NewConnectedPlug(s.plugSnap.Plugs["slot-plug-missing-mismatch"], nil, nil), 2280 Slot: interfaces.NewConnectedSlot(s.slotSnap.Slots["slot-plug-missing"], nil, nil), 2281 BaseDeclaration: s.baseDecl, 2282 } 2283 c.Check(cand.Check(), ErrorMatches, "connection not allowed.*") 2284 2285 // missing 2286 cand = policy.ConnectCandidate{ 2287 Plug: interfaces.NewConnectedPlug(s.plugSnap.Plugs["slot-plug-missing-match"], nil, nil), 2288 Slot: interfaces.NewConnectedSlot(s.slotSnap.Slots["slot-plug-missing"], nil, nil), 2289 BaseDeclaration: s.baseDecl, 2290 } 2291 c.Check(cand.Check(), IsNil) 2292 } 2293 2294 func (s *policySuite) TestSlotDollarPlugDynamicAttrConnection(c *C) { 2295 // "c" attribute of the plug missing 2296 cand := policy.ConnectCandidate{ 2297 Plug: interfaces.NewConnectedPlug(s.plugSnap.Plugs["slot-plug-attr-dynamic"], nil, map[string]interface{}{}), 2298 Slot: interfaces.NewConnectedSlot(s.slotSnap.Slots["slot-plug-attr"], nil, nil), 2299 BaseDeclaration: s.baseDecl, 2300 } 2301 c.Check(cand.Check(), ErrorMatches, "connection not allowed.*") 2302 2303 // plug attr == slot attr, "c" attribute of the plug provided by dynamic attribute 2304 cand = policy.ConnectCandidate{ 2305 Plug: interfaces.NewConnectedPlug(s.plugSnap.Plugs["slot-plug-attr-dynamic"], nil, map[string]interface{}{ 2306 "c": "C", 2307 }), 2308 2309 Slot: interfaces.NewConnectedSlot(s.slotSnap.Slots["slot-plug-attr"], nil, nil), 2310 BaseDeclaration: s.baseDecl, 2311 } 2312 c.Check(cand.Check(), IsNil) 2313 } 2314 2315 func (s *policySuite) TestPlugDollarSlotDynamicAttrConnection(c *C) { 2316 // "c" attribute of the slot missing 2317 cand := policy.ConnectCandidate{ 2318 Plug: interfaces.NewConnectedPlug(s.plugSnap.Plugs["plug-plug-attr"], nil, nil), 2319 Slot: interfaces.NewConnectedSlot(s.slotSnap.Slots["plug-plug-attr-dynamic"], nil, map[string]interface{}{}), 2320 BaseDeclaration: s.baseDecl, 2321 } 2322 c.Check(cand.Check(), ErrorMatches, "connection not allowed.*") 2323 2324 // plug attr == slot attr, "c" attribute of the slot provided by dynamic attribute 2325 cand = policy.ConnectCandidate{ 2326 Plug: interfaces.NewConnectedPlug(s.plugSnap.Plugs["plug-plug-attr"], nil, nil), 2327 Slot: interfaces.NewConnectedSlot(s.slotSnap.Slots["plug-plug-attr-dynamic"], nil, map[string]interface{}{ 2328 "c": "C", 2329 }), 2330 2331 BaseDeclaration: s.baseDecl, 2332 } 2333 c.Check(cand.Check(), IsNil) 2334 } 2335 2336 func (s *policySuite) TestSlotsArityAutoConnection(c *C) { 2337 tests := []struct { 2338 iface string 2339 any bool 2340 }{ 2341 {"slots-arity-default", false}, 2342 {"slots-arity-slot-any", true}, 2343 {"slots-arity-plug-any", true}, 2344 {"slots-arity-slot-any-plug-one", false}, 2345 {"slots-arity-slot-any-plug-two", false}, 2346 {"slots-arity-slot-any-plug-default", false}, 2347 {"slots-arity-slot-one-plug-any", true}, 2348 } 2349 2350 for _, t := range tests { 2351 cand := policy.ConnectCandidate{ 2352 Plug: interfaces.NewConnectedPlug(s.plugSnap.Plugs[t.iface], nil, nil), 2353 Slot: interfaces.NewConnectedSlot(s.slotSnap.Slots[t.iface], nil, nil), 2354 PlugSnapDeclaration: s.plugDecl, 2355 SlotSnapDeclaration: s.slotDecl, 2356 2357 BaseDeclaration: s.baseDecl, 2358 } 2359 arity, err := cand.CheckAutoConnect() 2360 c.Assert(err, IsNil) 2361 c.Check(arity.SlotsPerPlugAny(), Equals, t.any) 2362 } 2363 } 2364 2365 func (s *policySuite) TestNameConstraintsInstallation(c *C) { 2366 const plugSnap = `name: install-snap 2367 version: 0 2368 plugs: 2369 install-plug-name-bound:` 2370 2371 const plugOtherNameSnap = `name: install-snap 2372 version: 0 2373 plugs: 2374 install-plug-name-bound-other: 2375 interface: install-plug-name-bound 2376 ` 2377 2378 const slotSnap = `name: install-snap 2379 version: 0 2380 slots: 2381 install-slot-name-bound:` 2382 2383 const slotOtherNameSnap = `name: install-snap 2384 version: 0 2385 slots: 2386 install-slot-name-bound-other: 2387 interface: install-slot-name-bound 2388 ` 2389 2390 const plugOtherName = `plugs: 2391 install-plug-name-bound: 2392 allow-installation: 2393 plug-names: 2394 - install-plug-name-bound-other` 2395 2396 tests := []struct { 2397 installYaml string 2398 plugsSlots string 2399 err string // "" => no error 2400 }{ 2401 {plugSnap, "", ""}, 2402 {plugOtherNameSnap, "", `installation not allowed by "install-plug-name-bound-other" plug rule of interface "install-plug-name-bound"`}, 2403 {plugOtherNameSnap, plugOtherName, ""}, 2404 {slotSnap, "", ""}, 2405 {slotOtherNameSnap, "", `installation not allowed by "install-slot-name-bound-other" slot rule of interface "install-slot-name-bound"`}, 2406 } 2407 2408 for _, t := range tests { 2409 installSnap := snaptest.MockInfo(c, t.installYaml, nil) 2410 2411 plugsSlots := strings.TrimSpace(t.plugsSlots) 2412 if plugsSlots != "" { 2413 plugsSlots = "\n" + plugsSlots 2414 } 2415 2416 a, err := asserts.Decode([]byte(strings.Replace(`type: snap-declaration 2417 authority-id: canonical 2418 series: 16 2419 snap-name: install-snap 2420 snap-id: installsnap6idididididididididid 2421 publisher-id: publisher 2422 @plugsSlots@ 2423 timestamp: 2016-09-30T12:00:00Z 2424 sign-key-sha3-384: Jv8_JiHiIzJVcO9M55pPdqSDWUvuhfDIBJUS-3VW7F_idjix7Ffn5qMxB21ZQuij 2425 2426 AXNpZw==`, "\n@plugsSlots@", plugsSlots, 1))) 2427 c.Assert(err, IsNil) 2428 snapDecl := a.(*asserts.SnapDeclaration) 2429 2430 cand := policy.InstallCandidate{ 2431 Snap: installSnap, 2432 SnapDeclaration: snapDecl, 2433 BaseDeclaration: s.baseDecl, 2434 } 2435 err = cand.Check() 2436 if t.err == "" { 2437 c.Check(err, IsNil) 2438 } else { 2439 c.Check(err, ErrorMatches, t.err) 2440 } 2441 } 2442 } 2443 2444 func (s *policySuite) TestNameConstraintsAutoConnection(c *C) { 2445 tests := []struct { 2446 plug, slot string 2447 ok bool 2448 }{ 2449 {"plugs-name-bound-p1", "plugs-name-bound-s1", false}, 2450 {"plugs-name-bound-p2", "plugs-name-bound-s1", false}, 2451 {"plugs-name-bound-p1", "plugs-name-bound-s2", true}, 2452 {"plugs-name-bound-p2", "plugs-name-bound-s2", false}, 2453 {"slots-name-bound-p1", "slots-name-bound-s1", false}, 2454 {"slots-name-bound-p2", "slots-name-bound-s1", false}, 2455 {"slots-name-bound-p1", "slots-name-bound-s2", false}, 2456 {"slots-name-bound-p2", "slots-name-bound-s2", true}, 2457 } 2458 2459 for _, t := range tests { 2460 cand := policy.ConnectCandidate{ 2461 Plug: interfaces.NewConnectedPlug(s.plugSnap.Plugs[t.plug], nil, nil), 2462 Slot: interfaces.NewConnectedSlot(s.slotSnap.Slots[t.slot], nil, nil), 2463 PlugSnapDeclaration: s.plugDecl, 2464 SlotSnapDeclaration: s.slotDecl, 2465 2466 BaseDeclaration: s.baseDecl, 2467 } 2468 _, err := cand.CheckAutoConnect() 2469 if t.ok { 2470 c.Check(err, IsNil, Commentf("%s:%s", t.plug, t.slot)) 2471 } else { 2472 var expected string 2473 if cand.Plug.Interface() == "plugs-name-bound" { 2474 expected = `auto-connection not allowed by plug rule of interface "plugs-name-bound".*` 2475 } else { 2476 // slots-name-bound 2477 expected = `auto-connection not allowed by slot rule of interface "slots-name-bound".*` 2478 } 2479 c.Check(err, ErrorMatches, expected) 2480 } 2481 } 2482 2483 } 2484 2485 // Test miscellaneous store patterns when base declaration has 2486 // 'allow-installation: false' and we grant based on interface attributes 2487 // such as with personal-files, system-files, etc. 2488 // 2489 // While this is also tested elsewhere, combining this into a single test 2490 // makes it easy to verify correctness of a related set of patterns 2491 // 2492 // Eg, if base decl has: 2493 // slots: 2494 // system-files: 2495 // allow-installation: 2496 // slot-snap-type: 2497 // - core 2498 // plugs: 2499 // system-files: 2500 // allow-installation: false 2501 // 2502 // then test snap decls of the form: 2503 // plugs: 2504 // system-files: 2505 // allow-installation: 2506 // plug-attributes: 2507 // write: ... 2508 // or: 2509 // plugs: 2510 // system-files: 2511 // allow-installation: 2512 // - 2513 // plug-attributes: 2514 // write: ... 2515 // or: 2516 // plugs: 2517 // system-files: 2518 // allow-installation: 2519 // - 2520 // plug-attributes: 2521 // write: ... 2522 // - 2523 // plug-attributes: 2524 // write: ... 2525 // 2526 func (s *policySuite) TestSnapDeclListAttribWithBaseAllowInstallationFalse(c *C) { 2527 baseDeclStr := `type: base-declaration 2528 authority-id: canonical 2529 series: 16 2530 slots: 2531 base-allow-install-false: 2532 allow-installation: 2533 slot-snap-type: 2534 - core 2535 plugs: 2536 base-allow-install-false: 2537 allow-installation: false 2538 timestamp: 2016-09-30T12:00:00Z 2539 sign-key-sha3-384: Jv8_JiHiIzJVcO9M55pPdqSDWUvuhfDIBJUS-3VW7F_idjix7Ffn5qMxB21ZQuij 2540 2541 AXNpZw==` 2542 a, err := asserts.Decode([]byte(baseDeclStr)) 2543 c.Assert(err, IsNil) 2544 baseDecl := a.(*asserts.BaseDeclaration) 2545 2546 tests := []struct { 2547 installYaml string 2548 snapDeclPlugsSlots string 2549 expected string // "" => no error 2550 }{ 2551 // expected match 2552 {`name: install-snap 2553 version: 0 2554 plugs: 2555 p1: 2556 interface: base-allow-install-false 2557 write: 2558 - /path1 2559 `, `plugs: 2560 base-allow-install-false: 2561 allow-installation: 2562 plug-attributes: 2563 write: /path1 2564 `, ``}, 2565 {`name: install-snap 2566 version: 0 2567 plugs: 2568 p1: 2569 interface: base-allow-install-false 2570 write: 2571 - /path1 2572 `, `plugs: 2573 base-allow-install-false: 2574 allow-installation: 2575 plug-attributes: 2576 write: /path1a? 2577 `, ``}, 2578 {`name: install-snap 2579 version: 0 2580 plugs: 2581 p1: 2582 interface: base-allow-install-false 2583 write: 2584 - /path1a 2585 `, `plugs: 2586 base-allow-install-false: 2587 allow-installation: 2588 plug-attributes: 2589 write: /path1a? 2590 `, ``}, 2591 {`name: install-snap 2592 version: 0 2593 plugs: 2594 p1: 2595 interface: base-allow-install-false 2596 write: 2597 - /path1 2598 - /path1a 2599 `, `plugs: 2600 base-allow-install-false: 2601 allow-installation: 2602 plug-attributes: 2603 write: /path1a? 2604 `, ``}, 2605 2606 // expected match single alternation 2607 {`name: install-snap 2608 version: 0 2609 plugs: 2610 p1: 2611 interface: base-allow-install-false 2612 write: 2613 - /path1 2614 `, `plugs: 2615 base-allow-install-false: 2616 allow-installation: 2617 - 2618 plug-attributes: 2619 write: /path1 2620 `, ``}, 2621 {`name: install-snap 2622 version: 0 2623 plugs: 2624 p1: 2625 interface: base-allow-install-false 2626 write: 2627 - /path1 2628 `, `plugs: 2629 base-allow-install-false: 2630 allow-installation: 2631 - 2632 plug-attributes: 2633 write: /path1a? 2634 `, ``}, 2635 {`name: install-snap 2636 version: 0 2637 plugs: 2638 p1: 2639 interface: base-allow-install-false 2640 write: 2641 - /path1a 2642 `, `plugs: 2643 base-allow-install-false: 2644 allow-installation: 2645 - 2646 plug-attributes: 2647 write: /path1a? 2648 `, ``}, 2649 2650 {`name: install-snap 2651 version: 0 2652 plugs: 2653 p1: 2654 interface: base-allow-install-false 2655 write: 2656 - /path1 2657 - /path1a 2658 `, `plugs: 2659 base-allow-install-false: 2660 allow-installation: 2661 - 2662 plug-attributes: 2663 write: /path1a? 2664 `, ``}, 2665 // expected match two 2666 {`name: install-snap 2667 version: 0 2668 plugs: 2669 p1: 2670 interface: base-allow-install-false 2671 write: 2672 - /path1 2673 p2: 2674 interface: base-allow-install-false 2675 write: 2676 - /path1a 2677 `, `plugs: 2678 base-allow-install-false: 2679 allow-installation: 2680 plug-attributes: 2681 write: /path1a? 2682 `, ``}, 2683 {`name: install-snap 2684 version: 0 2685 plugs: 2686 p1: 2687 interface: base-allow-install-false 2688 write: 2689 - /path1 2690 p2: 2691 interface: base-allow-install-false 2692 write: 2693 - /path1a 2694 `, `plugs: 2695 base-allow-install-false: 2696 allow-installation: 2697 - 2698 plug-attributes: 2699 write: /path1a? 2700 `, ``}, 2701 {`name: install-snap 2702 version: 0 2703 plugs: 2704 p1: 2705 interface: base-allow-install-false 2706 write: 2707 - /path1 2708 p2: 2709 interface: base-allow-install-false 2710 write: 2711 - /path1a 2712 `, `plugs: 2713 base-allow-install-false: 2714 allow-installation: 2715 - 2716 plug-attributes: 2717 write: /path1 2718 - 2719 plug-attributes: 2720 write: /path1a 2721 `, ``}, 2722 // expected no match 2723 {`name: install-snap 2724 version: 0 2725 plugs: 2726 p1: 2727 interface: base-allow-install-false 2728 write: 2729 - /path1 2730 - /path1a 2731 `, `plugs: 2732 base-allow-install-false: 2733 allow-installation: 2734 plug-attributes: 2735 write: /path1 2736 `, `installation not allowed by "p1" plug rule of interface "base-allow-install-false" for "install-snap" snap`}, 2737 {`name: install-snap 2738 version: 0 2739 plugs: 2740 p1: 2741 interface: base-allow-install-false 2742 write: 2743 - /path1 2744 - /path1a 2745 `, `plugs: 2746 base-allow-install-false: 2747 allow-installation: 2748 - 2749 plug-attributes: 2750 write: /path1 2751 `, `installation not allowed by "p1" plug rule of interface "base-allow-install-false" for "install-snap" snap`}, 2752 {`name: install-snap 2753 version: 0 2754 plugs: 2755 p1: 2756 interface: base-allow-install-false 2757 write: 2758 - /path1 2759 p2: 2760 interface: base-allow-install-false 2761 write: 2762 - /path1nomatch 2763 `, `plugs: 2764 base-allow-install-false: 2765 allow-installation: 2766 - 2767 plug-attributes: 2768 write: /path1a? 2769 `, `installation not allowed by "p2" plug rule of interface "base-allow-install-false" for "install-snap" snap`}, 2770 {`name: install-snap 2771 version: 0 2772 plugs: 2773 p1: 2774 interface: base-allow-install-false 2775 write: 2776 - /path1 2777 p2: 2778 interface: base-allow-install-false 2779 write: 2780 - /path1nomatch 2781 `, `plugs: 2782 base-allow-install-false: 2783 allow-installation: 2784 - 2785 plug-attributes: 2786 write: /path1 2787 - 2788 plug-attributes: 2789 write: /path1a 2790 `, `installation not allowed by "p2" plug rule of interface "base-allow-install-false" for "install-snap" snap`}, 2791 {`name: install-snap 2792 version: 0 2793 plugs: 2794 p1: 2795 interface: base-allow-install-false 2796 `, `plugs: 2797 base-allow-install-false: 2798 allow-installation: 2799 plug-attributes: 2800 write: /path1 2801 `, `installation not allowed by "p1" plug rule of interface "base-allow-install-false" for "install-snap" snap`}, 2802 {`name: install-snap 2803 version: 0 2804 plugs: 2805 p1: 2806 interface: base-allow-install-false 2807 write: /path2 2808 `, `plugs: 2809 base-allow-install-false: 2810 allow-installation: 2811 plug-attributes: 2812 read: /path1 2813 write: /path2 2814 `, `installation not allowed by "p1" plug rule of interface "base-allow-install-false" for "install-snap" snap`}, 2815 } 2816 2817 for _, t := range tests { 2818 installSnap := snaptest.MockInfo(c, t.installYaml, nil) 2819 2820 snapDeclStr := strings.Replace(`type: snap-declaration 2821 authority-id: canonical 2822 series: 16 2823 snap-name: install-snap 2824 snap-id: installsnap6idididididididididid 2825 publisher-id: publisher 2826 @plugsSlots@ 2827 timestamp: 2016-09-30T12:00:00Z 2828 sign-key-sha3-384: Jv8_JiHiIzJVcO9M55pPdqSDWUvuhfDIBJUS-3VW7F_idjix7Ffn5qMxB21ZQuij 2829 2830 AXNpZw==`, "@plugsSlots@", strings.TrimSpace(t.snapDeclPlugsSlots), 1) 2831 b, err := asserts.Decode([]byte(snapDeclStr)) 2832 c.Assert(err, IsNil) 2833 snapDecl := b.(*asserts.SnapDeclaration) 2834 2835 cand := policy.InstallCandidate{ 2836 Snap: installSnap, 2837 SnapDeclaration: snapDecl, 2838 BaseDeclaration: baseDecl, 2839 } 2840 2841 err = cand.Check() 2842 if t.expected == "" { 2843 c.Check(err, IsNil) 2844 } else { 2845 c.Check(err, ErrorMatches, t.expected) 2846 } 2847 } 2848 }