diff --git a/.Dockerfiles/debian/stable/Dockerfile b/.Dockerfiles/debian/stable/Dockerfile new file mode 100644 index 00000000..0a6f4d92 --- /dev/null +++ b/.Dockerfiles/debian/stable/Dockerfile @@ -0,0 +1,66 @@ +FROM debian:stable + +ENV DEBIAN_FRONTEND="noninteractive" container="docker" + +RUN apt-get update \ + && apt-get upgrade -y \ + && apt-get install -y \ + apt-utils \ + curl \ + locales \ + lsb-release \ + net-tools \ + openssh-server \ + python-pip \ + python2.7 \ + sudo \ + systemd \ + && pip install --upgrade pip \ + && apt-get clean \ + && rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/* \ + && if ! getent passwd <%= @username %>; then \ + useradd -d /home/<%= @username %> -m -s /bin/bash -p '*' <%= @username %>; \ + fi \ + && echo "<%= @username %> ALL=(ALL) NOPASSWD: ALL" >> /etc/sudoers \ + && echo "Defaults !requiretty" >> /etc/sudoers \ + && mkdir -p /home/<%= @username %>/.ssh \ + && chown -R <%= @username %> /home/<%= @username %>/.ssh \ + && chmod 0700 /home/<%= @username %>/.ssh \ + && echo '<%= IO.read(@public_key).strip %>' >> /home/<%= @username %>/.ssh/authorized_keys \ + && chown <%= @username %> /home/<%= @username %>/.ssh/authorized_keys \ + && chmod 0600 /home/<%= @username %>/.ssh/authorized_keys \ + && echo "en_US.UTF-8 UTF-8" > /etc/locale.gen && locale-gen \ + && cd /lib/systemd/system/sysinit.target.wants/; ls | grep -v systemd-tmpfiles-setup | /usr/bin/xargs rm -f $1 \ + && /bin/rm -f /lib/systemd/system/multi-user.target.wants/* \ + && /bin/rm -f /etc/systemd/system/*.wants/* \ + && /bin/rm -f /lib/systemd/system/local-fs.target.wants/* \ + && /bin/rm -f /lib/systemd/system/sockets.target.wants/*udev* \ + && /bin/rm -f /lib/systemd/system/sockets.target.wants/*initctl* \ + && /bin/rm -f /lib/systemd/system/basic.target.wants/* \ + && /bin/rm -f /lib/systemd/system/anaconda.target.wants/* \ + && /bin/rm -f /lib/systemd/system/plymouth* \ + && /bin/rm -f /lib/systemd/system/systemd-update-utmp* \ + && sed -ri 's/^#?UsePAM\s+.*/UsePAM no/' /etc/ssh/sshd_config \ + && sed -ri 's/^#?PubkeyAuthentication\s+.*/PubkeyAuthentication yes/' /etc/ssh/sshd_config \ + && sed -ri 's/^#?UsePrivilegeSeparation\s+.*/UsePrivilegeSeparation no/' /etc/ssh/sshd_config \ + && echo "UseDNS=no" >> /etc/ssh/sshd_config \ + && systemctl set-default multi-user.target \ + && ln -s /lib/systemd/system/sshd.service /etc/systemd/system/multi-user.target.wants/sshd.service \ + && ln -s /lib/systemd/system/systemd-journald.service /etc/systemd/system/multi-user.target.wants/systemd-journald.service \ + && echo $'[Unit]\ +\nDescription=Finish boot up\ +\nAfter=ssh.service\ +\n\ +\n[Service]\ +\nType=oneshot\ +\nRemainAfterExit=yes\ +\nExecStartPre=/bin/sleep 3s\ +\nExecStart=/bin/rm -f /run/nologin\ +\n\ +\n[Install]\ +\nWantedBy=default.target' >> /etc/systemd/system/FinishBootUp.service \ + && ln -s /etc/systemd/system/FinishBootUp.service /etc/systemd/system/multi-user.target.wants/FinishBootUp.service + +EXPOSE 22 + +VOLUME [ "/sys/fs/cgroup" ] diff --git a/.Dockerfiles/fedora/latest/Dockerfile b/.Dockerfiles/fedora/latest/Dockerfile new file mode 100644 index 00000000..76df24ae --- /dev/null +++ b/.Dockerfiles/fedora/latest/Dockerfile @@ -0,0 +1,69 @@ +FROM fedora:latest + +ENV container="docker" + +RUN dnf clean all \ + && dnf makecache \ + && dnf install -y \ + curl \ + findutils \ + gcc \ + glibc-langpack-en.x86_64 \ + libffi-devel \ + net-tools \ + openssh-server \ + openssl-devel \ + python2-devel \ + python2-pip \ + redhat-lsb \ + redhat-rpm-config \ + sudo \ + systemd \ + && pip install --upgrade pip \ + && dnf clean all \ + && if ! getent passwd <%= @username %>; then \ + useradd -d /home/<%= @username %> -m -s /usr/bin/bash -p '*' <%= @username %>; \ + fi \ + && echo "<%= @username %> ALL=(ALL) NOPASSWD: ALL" >> /etc/sudoers \ + && echo "Defaults !requiretty" >> /etc/sudoers \ + && mkdir -p /home/<%= @username %>/.ssh \ + && chown -R <%= @username %> /home/<%= @username %>/.ssh \ + && chmod 0700 /home/<%= @username %>/.ssh \ + && echo '<%= IO.read(@public_key).strip %>' >> /home/<%= @username %>/.ssh/authorized_keys \ + && chown <%= @username %> /home/<%= @username %>/.ssh/authorized_keys \ + && chmod 0600 /home/<%= @username %>/.ssh/authorized_keys \ + && export LANG="en_US.UTF-8" && echo "LANG=\"en_US.UTF-8\"" > /etc/locale.conf \ + && cd /lib/systemd/system/sysinit.target.wants/; ls | grep -v systemd-tmpfiles-setup | /usr/bin/xargs rm -f $1 \ + && /usr/bin/rm -f /lib/systemd/system/multi-user.target.wants/* \ + && /usr/bin/rm -f /etc/systemd/system/*.wants/* \ + && /usr/bin/rm -f /lib/systemd/system/local-fs.target.wants/* \ + && /usr/bin/rm -f /lib/systemd/system/sockets.target.wants/*udev* \ + && /usr/bin/rm -f /lib/systemd/system/sockets.target.wants/*initctl* \ + && /usr/bin/rm -f /lib/systemd/system/basic.target.wants/* \ + && /usr/bin/rm -f /lib/systemd/system/anaconda.target.wants/* \ + && /usr/bin/rm -f /lib/systemd/system/plymouth* \ + && /usr/bin/rm -f /lib/systemd/system/systemd-update-utmp* \ + && sed -ri 's/^#?PubkeyAuthentication\s+.*/PubkeyAuthentication yes/' /etc/ssh/sshd_config \ + && sed -ri 's/^#?UsePrivilegeSeparation\s+.*/UsePrivilegeSeparation no/' /etc/ssh/sshd_config \ + && echo "UseDNS=no" >> /etc/ssh/sshd_config \ + && systemctl set-default multi-user.target \ + && ln -s /lib/systemd/system/sshd.service /etc/systemd/system/multi-user.target.wants/sshd.service \ + && ln -s /lib/systemd/system/systemd-journald.service /etc/systemd/system/multi-user.target.wants/systemd-journald.service \ + && echo $'[Unit]\ +\nDescription=Finish boot up\ +\nAfter=ssh.service\ +\n\ +\n[Service]\ +\nType=oneshot\ +\nRemainAfterExit=yes\ +\nExecStartPre=/bin/sleep 3s\ +\nExecStart=/bin/rm -f /run/nologin\ +\n\ +\n[Install]\ +\nWantedBy=default.target' >> /etc/systemd/system/FinishBootUp.service \ + && ln -s /etc/systemd/system/FinishBootUp.service /etc/systemd/system/multi-user.target.wants/FinishBootUp.service + + +EXPOSE 22 + +VOLUME [ "/sys/fs/cgroup" ] diff --git a/.Dockerfiles/ubuntu/latest/Dockerfile b/.Dockerfiles/ubuntu/latest/Dockerfile new file mode 100644 index 00000000..c2ce45ed --- /dev/null +++ b/.Dockerfiles/ubuntu/latest/Dockerfile @@ -0,0 +1,66 @@ +FROM ubuntu:latest + +ENV DEBIAN_FRONTEND="noninteractive" container="docker" + +RUN apt-get update \ + && apt-get upgrade -y \ + && apt-get install -y \ + apt-utils \ + curl \ + locales \ + lsb-release \ + net-tools \ + openssh-server \ + python-pip \ + python2.7 \ + sudo \ + systemd \ + && pip install --upgrade pip \ + && apt-get clean \ + && rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/* \ + && if ! getent passwd <%= @username %>; then \ + useradd -d /home/<%= @username %> -m -s /bin/bash -p '*' <%= @username %>; \ + fi \ + && echo "<%= @username %> ALL=(ALL) NOPASSWD: ALL" >> /etc/sudoers \ + && echo "Defaults !requiretty" >> /etc/sudoers \ + && mkdir -p /home/<%= @username %>/.ssh \ + && chown -R <%= @username %> /home/<%= @username %>/.ssh \ + && chmod 0700 /home/<%= @username %>/.ssh \ + && echo '<%= IO.read(@public_key).strip %>' >> /home/<%= @username %>/.ssh/authorized_keys \ + && chown <%= @username %> /home/<%= @username %>/.ssh/authorized_keys \ + && chmod 0600 /home/<%= @username %>/.ssh/authorized_keys \ + && echo "en_US.UTF-8 UTF-8" > /etc/locale.gen && /usr/sbin/locale-gen \ + && cd /lib/systemd/system/sysinit.target.wants/; ls | grep -v systemd-tmpfiles-setup | xargs rm -f $1 \ + && /bin/rm -f /lib/systemd/system/multi-user.target.wants/* \ + && /bin/rm -f /etc/systemd/system/*.wants/* \ + && /bin/rm -f /lib/systemd/system/local-fs.target.wants/* \ + && /bin/rm -f /lib/systemd/system/sockets.target.wants/*udev* \ + && /bin/rm -f /lib/systemd/system/sockets.target.wants/*initctl* \ + && /bin/rm -f /lib/systemd/system/basic.target.wants/* \ + && /bin/rm -f /lib/systemd/system/anaconda.target.wants/* \ + && /bin/rm -f /lib/systemd/system/plymouth* \ + && /bin/rm -f /lib/systemd/system/systemd-update-utmp* \ + && sed -ri 's/^#?UsePAM\s+.*/UsePAM no/' /etc/ssh/sshd_config \ + && sed -ri 's/^#?PubkeyAuthentication\s+.*/PubkeyAuthentication yes/' /etc/ssh/sshd_config \ + && sed -ri 's/^#?UsePrivilegeSeparation\s+.*/UsePrivilegeSeparation no/' /etc/ssh/sshd_config \ + && echo "UseDNS=no" >> /etc/ssh/sshd_config \ + && systemctl set-default multi-user.target \ + && ln -s /lib/systemd/system/sshd.service /etc/systemd/system/multi-user.target.wants/sshd.service \ + && ln -s /lib/systemd/system/systemd-journald.service /etc/systemd/system/multi-user.target.wants/systemd-journald.service \ + && echo $'[Unit]\ +\nDescription=Finish boot up\ +\nAfter=ssh.service\ +\n\ +\n[Service]\ +\nType=oneshot\ +\nRemainAfterExit=yes\ +\nExecStartPre=/bin/sleep 3s\ +\nExecStart=/bin/rm -f /run/nologin\ +\n\ +\n[Install]\ +\nWantedBy=default.target' >> /etc/systemd/system/FinishBootUp.service \ + && ln -s /etc/systemd/system/FinishBootUp.service /etc/systemd/system/multi-user.target.wants/FinishBootUp.service + +EXPOSE 22 + +VOLUME [ "/sys/fs/cgroup" ] diff --git a/.Dockerfiles/ubuntu/rolling/Dockerfile b/.Dockerfiles/ubuntu/rolling/Dockerfile new file mode 100644 index 00000000..17b8dde7 --- /dev/null +++ b/.Dockerfiles/ubuntu/rolling/Dockerfile @@ -0,0 +1,66 @@ +FROM ubuntu:rolling + +ENV DEBIAN_FRONTEND="noninteractive" container="docker" + +RUN apt-get update \ + && apt-get upgrade -y \ + && apt-get install -y \ + apt-utils \ + curl \ + locales \ + lsb-release \ + net-tools \ + openssh-server \ + python-pip \ + python2.7 \ + sudo \ + systemd \ + && pip install --upgrade pip \ + && apt-get clean \ + && rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/* \ + && if ! getent passwd <%= @username %>; then \ + useradd -d /home/<%= @username %> -m -s /bin/bash -p '*' <%= @username %>; \ + fi \ + && echo "<%= @username %> ALL=(ALL) NOPASSWD: ALL" >> /etc/sudoers \ + && echo "Defaults !requiretty" >> /etc/sudoers \ + && mkdir -p /home/<%= @username %>/.ssh \ + && chown -R <%= @username %> /home/<%= @username %>/.ssh \ + && chmod 0700 /home/<%= @username %>/.ssh \ + && echo '<%= IO.read(@public_key).strip %>' >> /home/<%= @username %>/.ssh/authorized_keys \ + && chown <%= @username %> /home/<%= @username %>/.ssh/authorized_keys \ + && chmod 0600 /home/<%= @username %>/.ssh/authorized_keys \ + && echo "en_US.UTF-8 UTF-8" > /etc/locale.gen && /usr/sbin/locale-gen \ + && cd /lib/systemd/system/sysinit.target.wants/; ls | grep -v systemd-tmpfiles-setup | xargs rm -f $1 \ + && /bin/rm -f /lib/systemd/system/multi-user.target.wants/* \ + && /bin/rm -f /etc/systemd/system/*.wants/* \ + && /bin/rm -f /lib/systemd/system/local-fs.target.wants/* \ + && /bin/rm -f /lib/systemd/system/sockets.target.wants/*udev* \ + && /bin/rm -f /lib/systemd/system/sockets.target.wants/*initctl* \ + && /bin/rm -f /lib/systemd/system/basic.target.wants/* \ + && /bin/rm -f /lib/systemd/system/anaconda.target.wants/* \ + && /bin/rm -f /lib/systemd/system/plymouth* \ + && /bin/rm -f /lib/systemd/system/systemd-update-utmp* \ + && sed -ri 's/^#?UsePAM\s+.*/UsePAM no/' /etc/ssh/sshd_config \ + && sed -ri 's/^#?PubkeyAuthentication\s+.*/PubkeyAuthentication yes/' /etc/ssh/sshd_config \ + && sed -ri 's/^#?UsePrivilegeSeparation\s+.*/UsePrivilegeSeparation no/' /etc/ssh/sshd_config \ + && echo "UseDNS=no" >> /etc/ssh/sshd_config \ + && systemctl set-default multi-user.target \ + && ln -s /lib/systemd/system/sshd.service /etc/systemd/system/multi-user.target.wants/sshd.service \ + && ln -s /lib/systemd/system/systemd-journald.service /etc/systemd/system/multi-user.target.wants/systemd-journald.service \ + && echo $'[Unit]\ +\nDescription=Finish boot up\ +\nAfter=ssh.service\ +\n\ +\n[Service]\ +\nType=oneshot\ +\nRemainAfterExit=yes\ +\nExecStartPre=/bin/sleep 3s\ +\nExecStart=/bin/rm -f /run/nologin\ +\n\ +\n[Install]\ +\nWantedBy=default.target' >> /etc/systemd/system/FinishBootUp.service \ + && ln -s /etc/systemd/system/FinishBootUp.service /etc/systemd/system/multi-user.target.wants/FinishBootUp.service + +EXPOSE 22 + +VOLUME [ "/sys/fs/cgroup" ] diff --git a/.ci-tests/integration/gnupg-git/default.yml b/.ci-tests/integration/gnupg-git/default.yml new file mode 100644 index 00000000..bb92b633 --- /dev/null +++ b/.ci-tests/integration/gnupg-git/default.yml @@ -0,0 +1,131 @@ +--- +# host to test against +- hosts: test-kitchen + remote_user: root + tasks: + - include_tasks: tasks/dependencies.yml + + - name: Install build tools + package: + name: "{{ item }}" + with_items: "{{ build_tools }}" + + - name: Check wether deb-src repos are enabled + command: grep -c -e "^deb-src.*" /etc/apt/sources.list + register: deb_src_check + ignore_errors: yes + when: + - ansible_os_family == "Debian" + + - name: Set deb-src check results + set_fact: + deb_src_check_result: "{{ deb_src_check.stdout | default(0) | int }}" + + - name: Enable Ubuntu main & restricted source repo + replace: + path: '/etc/apt/sources.list' + regexp: '^(#\s)(.*main\srestricted)$' + replace: '\2 # enabled' + when: + - ansible_distribution == "Ubuntu" + - deb_src_check_result >= 1 + + - name: Enable Debian source repos + replace: + path: '/etc/apt/sources.list' + regexp: '^(deb)(.*)$' + replace: '\1\2\ndeb-src\2' + when: + - ansible_distribution == "Debian" + - deb_src_check_result >= 1 + + - name: Install gnupg build dependencies for Debian based distros + apt: + name: gnupg2 + state: build-dep + update_cache: yes + when: + - ansible_os_family == "Debian" + + - name: Install gnupg build dependencies for RedHat based distros + command: bash -lc "yum --assumeyes install yum-utils && yum-builddep --assumeyes gnupg2" + when: + - ansible_os_family == "RedHat" + + - name: Get GnuPG github api content + uri: + url: https://api.github.com/repos/gpg/gnupg/tags + method: GET + return_content: yes + body_format: json + register: gnupg_tags + + - name: Set url for latest gnupg release source + set_fact: + gnupg_tarball_url: >- + {{ + gnupg_tags.json | + selectattr('name','match','gnupg-2.*') | + map(attribute='tarball_url') | first + }} + + - name: Download latest release of gnupg source + get_url: + url: "{{ gnupg_tarball_url }}" + dest: /tmp/gnupg.tar.gz + force: yes + retries: 5 + delay: 10 + + - name: Extract gnupg source tarball + unarchive: + src: /tmp/gnupg.tar.gz + dest: /usr/local/src/ + + - name: Find gnupg src directory + find: + paths: /usr/local/src + patterns: "gpg-gnupg*" + file_type: directory + recurse: no + register: found_gpg_src + + - name: Set gnupg src directory + set_fact: + gpg_src_path: "{{ found_gpg_src.files | map(attribute='path') | first }}" + + - name: Run gnupg autogen + command: bash -lc "cd {{ gpg_src_path }} && ./autogen.sh " + changed_when: False + + - name: Disable development msg for gnupg + lineinfile: + path: "{{ gpg_src_path }}/configure" + regexp: '^development_version=.*' + line: 'development_version=no' + + - name: Set gnupg build config + set_fact: + gpg_build_config: >- + --sysconfdir=/etc + --prefix=/usr + --enable-symcryptrun + --docdir=/usr/share/doc/gnupg-2.2.0 + --disable-rpath + --enable-maintainer-mode + changed_when: False + + - name: Configure gnupg build + command: bash -lc "cd {{ gpg_src_path }} && ./configure {{ gpg_build_config }}" + changed_when: False + + - name: Compile gnupg src + command: bash -lc "cd {{ gpg_src_path }} && make" + changed_when: False + + - name: Install compiled gnupg + command: bash -lc "cd {{ gpg_src_path }} && make install" + changed_when: False + + - include_tasks: tasks/prep-tests.yml + - include_tasks: tasks/run-tests.yml diff --git a/.ci-tests/integration/gnupg-git/serverspec/default_spec.rb b/.ci-tests/integration/gnupg-git/serverspec/default_spec.rb new file mode 100644 index 00000000..9da394c6 --- /dev/null +++ b/.ci-tests/integration/gnupg-git/serverspec/default_spec.rb @@ -0,0 +1,45 @@ +require_relative './spec_helper' + +describe 'git-secret::test' do + + describe package('git-secret') do + it { should be_installed } + end + + if host_inventory['platform'] == 'fedora' + describe command('find /tmp/git-secret/build -name "*.rpm"') do + its(:stdout) { should match /git-secret.*rpm/ } + end + else + describe command('find /tmp/git-secret/build -name "*.deb"') do + its(:stdout) { should match /git-secret.*deb/ } + end + end + + describe file('/.git-secret_test-passed') do + it { should exist } + end + + describe file('/.git-secret_lint-passed') do + it { should exist } + end + + if host_inventory['platform'] == 'fedora' + describe command('rpm --query --info git-secret') do + its(:exit_status) { should eq 0 } + end + else + describe command('dpkg-query --status git-secret') do + its(:exit_status) { should eq 0 } + end + end + + describe command('man --where "git-secret"') do + its(:exit_status) { should eq 0 } + end + + describe command('man --where "git-secret-init"') do + its(:exit_status) { should eq 0 } + end + +end diff --git a/.ci-tests/integration/gnupg-git/serverspec/spec_helper.rb b/.ci-tests/integration/gnupg-git/serverspec/spec_helper.rb new file mode 100644 index 00000000..a9c6f99d --- /dev/null +++ b/.ci-tests/integration/gnupg-git/serverspec/spec_helper.rb @@ -0,0 +1,11 @@ +require 'serverspec' + +# :backend can be either :exec or :ssh +# since we are running local we use :exec +set :backend, :exec + +RSpec.configure do |c| + c.before :all do + c.path = '/usr/local/bin:/bin:/usr/bin:/usr/local/sbin:/usr/sbin:/sbin' + end +end diff --git a/.ci-tests/integration/gnupg1/default.yml b/.ci-tests/integration/gnupg1/default.yml new file mode 100644 index 00000000..bbe8afed --- /dev/null +++ b/.ci-tests/integration/gnupg1/default.yml @@ -0,0 +1,34 @@ +--- +# host to test against +- hosts: test-kitchen + remote_user: root + tasks: + - include_tasks: tasks/dependencies.yml + + - name: Install gnupg + package: + name: "{{ item.name }}" + state: present + when: + - ansible_distribution == item.distribution + with_items: + - name: gnupg + distribution: Fedora + - name: gnupg1 + distribution: Debian + + - name: Check for gpg1 binary + stat: + path: /usr/bin/gpg1 + register: gpg1 + + - name: Make gpg1 default binary + file: + src: /usr/bin/gpg1 + dest: /usr/bin/gpg + state: link + force: yes + when: gpg1.stat.exists + + - include_tasks: tasks/prep-tests.yml + - include_tasks: tasks/run-tests.yml diff --git a/.ci-tests/integration/gnupg1/serverspec/default_spec.rb b/.ci-tests/integration/gnupg1/serverspec/default_spec.rb new file mode 100644 index 00000000..9da394c6 --- /dev/null +++ b/.ci-tests/integration/gnupg1/serverspec/default_spec.rb @@ -0,0 +1,45 @@ +require_relative './spec_helper' + +describe 'git-secret::test' do + + describe package('git-secret') do + it { should be_installed } + end + + if host_inventory['platform'] == 'fedora' + describe command('find /tmp/git-secret/build -name "*.rpm"') do + its(:stdout) { should match /git-secret.*rpm/ } + end + else + describe command('find /tmp/git-secret/build -name "*.deb"') do + its(:stdout) { should match /git-secret.*deb/ } + end + end + + describe file('/.git-secret_test-passed') do + it { should exist } + end + + describe file('/.git-secret_lint-passed') do + it { should exist } + end + + if host_inventory['platform'] == 'fedora' + describe command('rpm --query --info git-secret') do + its(:exit_status) { should eq 0 } + end + else + describe command('dpkg-query --status git-secret') do + its(:exit_status) { should eq 0 } + end + end + + describe command('man --where "git-secret"') do + its(:exit_status) { should eq 0 } + end + + describe command('man --where "git-secret-init"') do + its(:exit_status) { should eq 0 } + end + +end diff --git a/.ci-tests/integration/gnupg1/serverspec/spec_helper.rb b/.ci-tests/integration/gnupg1/serverspec/spec_helper.rb new file mode 100644 index 00000000..a9c6f99d --- /dev/null +++ b/.ci-tests/integration/gnupg1/serverspec/spec_helper.rb @@ -0,0 +1,11 @@ +require 'serverspec' + +# :backend can be either :exec or :ssh +# since we are running local we use :exec +set :backend, :exec + +RSpec.configure do |c| + c.before :all do + c.path = '/usr/local/bin:/bin:/usr/bin:/usr/local/sbin:/usr/sbin:/sbin' + end +end diff --git a/.ci-tests/integration/gnupg2/default.yml b/.ci-tests/integration/gnupg2/default.yml new file mode 100644 index 00000000..662da7d2 --- /dev/null +++ b/.ci-tests/integration/gnupg2/default.yml @@ -0,0 +1,38 @@ +--- +# host to test against +- hosts: test-kitchen + remote_user: root + tasks: + - include_tasks: tasks/dependencies.yml + + - name: Install gnupg + package: + name: "{{ item.name }}" + state: present + when: + - ansible_distribution == item.distribution + with_items: + - name: gnupg2 + distribution: Fedora + - name: gnupg2 + distribution: Ubuntu + - name: gnupg + distribution: Debian + + - name: Check for gpg2 binary + stat: + path: /usr/bin/gpg2 + register: gpg2 + + - name: Make gpg2 default binary + file: + src: /usr/bin/gpg2 + dest: /usr/bin/gpg + state: link + force: yes + when: + - gpg2.stat.exists + - gpg2.stat.islnk == False + + - include_tasks: tasks/prep-tests.yml + - include_tasks: tasks/run-tests.yml diff --git a/.ci-tests/integration/gnupg2/serverspec/default_spec.rb b/.ci-tests/integration/gnupg2/serverspec/default_spec.rb new file mode 100644 index 00000000..9da394c6 --- /dev/null +++ b/.ci-tests/integration/gnupg2/serverspec/default_spec.rb @@ -0,0 +1,45 @@ +require_relative './spec_helper' + +describe 'git-secret::test' do + + describe package('git-secret') do + it { should be_installed } + end + + if host_inventory['platform'] == 'fedora' + describe command('find /tmp/git-secret/build -name "*.rpm"') do + its(:stdout) { should match /git-secret.*rpm/ } + end + else + describe command('find /tmp/git-secret/build -name "*.deb"') do + its(:stdout) { should match /git-secret.*deb/ } + end + end + + describe file('/.git-secret_test-passed') do + it { should exist } + end + + describe file('/.git-secret_lint-passed') do + it { should exist } + end + + if host_inventory['platform'] == 'fedora' + describe command('rpm --query --info git-secret') do + its(:exit_status) { should eq 0 } + end + else + describe command('dpkg-query --status git-secret') do + its(:exit_status) { should eq 0 } + end + end + + describe command('man --where "git-secret"') do + its(:exit_status) { should eq 0 } + end + + describe command('man --where "git-secret-init"') do + its(:exit_status) { should eq 0 } + end + +end diff --git a/.ci-tests/integration/gnupg2/serverspec/spec_helper.rb b/.ci-tests/integration/gnupg2/serverspec/spec_helper.rb new file mode 100644 index 00000000..a9c6f99d --- /dev/null +++ b/.ci-tests/integration/gnupg2/serverspec/spec_helper.rb @@ -0,0 +1,11 @@ +require 'serverspec' + +# :backend can be either :exec or :ssh +# since we are running local we use :exec +set :backend, :exec + +RSpec.configure do |c| + c.before :all do + c.path = '/usr/local/bin:/bin:/usr/bin:/usr/local/sbin:/usr/sbin:/sbin' + end +end diff --git a/.ci-tests/integration/tasks/dependencies.yml b/.ci-tests/integration/tasks/dependencies.yml new file mode 100644 index 00000000..ce2f65d1 --- /dev/null +++ b/.ci-tests/integration/tasks/dependencies.yml @@ -0,0 +1,30 @@ +--- +- name: Load a variable file based on the OS type, or a default if not found. + include_vars: "{{ item }}" + with_first_found: + - "{{ ansible_distribution }}.yml" + - "{{ ansible_os_family }}.yml" + - "default.yml" + +- name: Install Dependencies + package: + name: "{{ item }}" + state: present + with_items: "{{ test_dependencies }}" + +- name: Get bats + git: + repo: 'https://github.com/sstephenson/bats.git' + dest: /opt/bats + +- name: Install bats + file: + src: /opt/bats/libexec/bats + dest: /usr/bin/bats + state: link + +- name: Install fpm + gem: + name: fpm + state: present + user_install: no diff --git a/.ci-tests/integration/tasks/prep-tests.yml b/.ci-tests/integration/tasks/prep-tests.yml new file mode 100644 index 00000000..d3993b10 --- /dev/null +++ b/.ci-tests/integration/tasks/prep-tests.yml @@ -0,0 +1,31 @@ +--- +- name: Get OS package type + set_fact: + os_pkg_type: "{{ item.os_pkg_type }}" + when: + - item.os_family == ansible_os_family + with_items: + - os_family: RedHat + os_pkg_type: "rpm" + - os_family: Debian + os_pkg_type: "deb" + - os_family: Suse + os_pkg_type: "rpm" + changed_when: false + tags: + - skip_ansible_lint + +- name: Get gpg version + command: gpg --version + register: gpg_version + changed_when: False + +- name: Print gpg version + debug: + msg: "Running test againts {{ gpg_version.stdout_lines | first | string }}." + changed_when: False + +- name: Copy git-secret src + synchronize: + src: /opt/workspace/ + dest: /tmp/git-secret diff --git a/.ci-tests/integration/tasks/run-tests.yml b/.ci-tests/integration/tasks/run-tests.yml new file mode 100644 index 00000000..dbe8b371 --- /dev/null +++ b/.ci-tests/integration/tasks/run-tests.yml @@ -0,0 +1,65 @@ +--- +- name: Run ci-test + command: bash -lc "cd /tmp/git-secret && make test" + changed_when: False + ignore_errors: yes + register: test_results + environment: + PATH: /usr/local/bin:{{ ansible_env.PATH }} + +- name: Print ci-test results + debug: + var: test_results.stdout_lines + +- name: Create file when ci-test passes + file: + path: /.git-secret_test-passed + state: touch + when: + - test_results.rc == 0 + +- name: Run lint + command: bash -lc "cd /tmp/git-secret && make lint" + ignore_errors: yes + register: lint_results + changed_when: False + +- name: Print lint results + debug: + var: lint_results.stdout_lines + +- name: Create file when lint passes + file: + path: /.git-secret_lint-passed + state: touch + when: + - lint_results.rc == 0 + +- name: Create git-secret {{ os_pkg_type }} package + command: bash -lc "cd /tmp/git-secret && make build-{{ os_pkg_type }}" + changed_when: False + ignore_errors: yes + register: test_results + environment: + PATH: /usr/local/bin:{{ ansible_env.PATH }} + +- name: Find git-secret {{ os_pkg_type }} file + find: + paths: /tmp/git-secret/build + patterns: "*.{{ os_pkg_type }}" + recurse: yes + register: pkg_location + +- name: Set git-secret {{ os_pkg_type }} location + set_fact: + pkg_path: "{{ pkg_location.files | map(attribute='path') | first }}" + +- name: Install git-secret {{ os_pkg_type }} package + command: bash -lc "{{ item.command }} {{ pkg_path }}" + when: + - item.os_family == ansible_os_family + with_items: + - command: "rpm --nodeps --install --force" + os_family: "RedHat" + - command: "dpkg --force-all --install" + os_family: "Debian" diff --git a/.ci-tests/integration/vars/Debian.yml b/.ci-tests/integration/vars/Debian.yml new file mode 100644 index 00000000..535c5222 --- /dev/null +++ b/.ci-tests/integration/vars/Debian.yml @@ -0,0 +1,17 @@ +--- +test_dependencies: + - gawk + - make + - git + - shellcheck + - ruby-dev + - rubygems + - man + +build_tools: + - autoconf + - automake + - build-essential + - imagemagick + - texinfo + - transfig diff --git a/.ci-tests/integration/vars/Fedora.yml b/.ci-tests/integration/vars/Fedora.yml new file mode 100644 index 00000000..9e85b2c1 --- /dev/null +++ b/.ci-tests/integration/vars/Fedora.yml @@ -0,0 +1,20 @@ +--- +test_dependencies: + - ShellCheck + - gawk + - git + - make + - man + - redhat-rpm-config + - rpm-build + - rsync + - ruby-devel + - rubygems + - rubygems-devel + +build_tools: + - ImageMagick + - autoconf + - automake + - texinfo + - transfig diff --git a/.ci-tests/integration/vars/Ubuntu.yml b/.ci-tests/integration/vars/Ubuntu.yml new file mode 100644 index 00000000..a55e4966 --- /dev/null +++ b/.ci-tests/integration/vars/Ubuntu.yml @@ -0,0 +1,17 @@ +--- +test_dependencies: + - gawk + - git + - make + - man + - ruby-dev + - rubygems + - shellcheck + +build_tools: + - autoconf + - automake + - build-essential + - imagemagick + - texinfo + - transfig diff --git a/.ci-tests/integration/vars/default.yml b/.ci-tests/integration/vars/default.yml new file mode 100644 index 00000000..535c5222 --- /dev/null +++ b/.ci-tests/integration/vars/default.yml @@ -0,0 +1,17 @@ +--- +test_dependencies: + - gawk + - make + - git + - shellcheck + - ruby-dev + - rubygems + - man + +build_tools: + - autoconf + - automake + - build-essential + - imagemagick + - texinfo + - transfig diff --git a/.gitignore b/.gitignore index 309b6085..45b8a5df 100644 --- a/.gitignore +++ b/.gitignore @@ -133,3 +133,7 @@ temp/ build/ *.deb *.fpm + +# Kithcne files +Gemfile.lock +.kitchen/ diff --git a/.kitchen.yml b/.kitchen.yml new file mode 100644 index 00000000..763547e2 --- /dev/null +++ b/.kitchen.yml @@ -0,0 +1,112 @@ +--- +driver: + name: docker + use_sudo: false + +provisioner: + # name of the host + hosts: test-kitchen + # use an ansible playbook to provision our server + name: ansible_playbook + ansible_verbose: false + require_ansible_repo: false + require_ansible_omnibus: true + ansible_version: 2.4 + require_chef_for_busser: false + sudo_command: sudo -E -H + idempotency_test: false + sudo: true + ansible_extra_flags: "-e '{ kitchen_testrun: True }'" + additional_copy_path: + - ".ci-tests/integration/vars" + - ".ci-tests/integration/tasks" + +transport: + max_ssh_sessions: 3 + +platforms: + - name: debian-stable + driver_config: + run_command: /lib/systemd/systemd + dockerfile: .Dockerfiles/debian/stable/Dockerfile + platform: debian + cap_add: + - SYS_ADMIN + volume: + - /sys/fs/cgroup:/sys/fs/cgroup:ro + - <%=ENV['PWD']%>:/opt/workspace # Make the working directory available inside the container + run_options: + tmpfs: + - /run + + - name: fedora-latest + driver_config: + run_command: /lib/systemd/systemd + dockerfile: .Dockerfiles/fedora/latest/Dockerfile + platform: fedora + cap_add: + - SYS_ADMIN + volume: + - /sys/fs/cgroup:/sys/fs/cgroup:ro + - <%=ENV['PWD']%>:/opt/workspace # Make the working directory available inside the container + run_options: + tmpfs: + - /run + + - name: ubuntu-latest + driver_config: + run_command: /lib/systemd/systemd + dockerfile: .Dockerfiles/ubuntu/latest/Dockerfile + platform: ubuntu + cap_add: + - SYS_ADMIN + volume: + - /sys/fs/cgroup:/sys/fs/cgroup:ro + - <%=ENV['PWD']%>:/opt/workspace # Make the working directory available inside the container + run_options: + tmpfs: + - /run + + - name: ubuntu-rolling + driver_config: + run_command: /lib/systemd/systemd + dockerfile: .Dockerfiles/ubuntu/rolling/Dockerfile + platform: ubuntu + cap_add: + - SYS_ADMIN + volume: + - /sys/fs/cgroup:/sys/fs/cgroup:ro + - <%=ENV['PWD']%>:/opt/workspace # Make the working directory available inside the container + run_options: + tmpfs: + - /run + +verifier: + name: serverspec + sudo_path: true + +suites: + # suites found at /test/integration/$test-name + # in container @/tmp/kitchen + - name: gnupg1 + verifier: + patterns: + - roles/git-secret/.ci-tests/integration/gnupg1/serverspec/*_spec.rb + bundler_path: '/usr/local/bin' + rspec_path: '/usr/local/bin' + - name: gnupg2 + verifier: + patterns: + - roles/git-secret/.ci-tests/integration/gnupg2/serverspec/*_spec.rb + bundler_path: '/usr/local/bin' + rspec_path: '/usr/local/bin' + excludes: + - ubuntu-latest + - name: gnupg-git + verifier: + patterns: + - roles/git-secret/.ci-tests/integration/gnupg-git/serverspec/*_spec.rb + bundler_path: '/usr/local/bin' + rspec_path: '/usr/local/bin' + excludes: + - ubuntu-latest diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index b95d927b..405d1297 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -10,8 +10,14 @@ Before starting make sure you have: - git - bash +- bundler +- docker +- gawk - gnupg (or gnupg2) +- ruby +- sha256sum - [shellcheck](https://github.com/koalaman/shellcheck) +- test-kitchen Only required if dealing with manuals, `gh-pages` or releases: @@ -21,7 +27,8 @@ Only required if dealing with manuals, `gh-pages` or releases: 1. Create your own or pick an opened issue from the [tracker][tracker]. Take a look at the [`help-wanted` tag][help-wanted] 2. Fork and clone your repository: `git clone https://github.com/${YOUR_NAME}/git-secret.git` -3. Make sure that everything works fine by running `make test` +3. Make sure that everything works on the current platform by running `make test` +4. [Run local CI tests](#running-local-ci-tests) to verify functionality on supported platforms `bundle exec kitchen verify --test-base-path="$PWD/.ci-tests/integration"`. ### Development Process @@ -46,12 +53,20 @@ It basically looks like that: ### Continuous integration -CI is done with the help of `travis`. `travis` handles multiple environments: +Local CI is done with the help [`test-kitchen`](http://kitchen.ci/). `test-kitchen` handles multiple test-suites on various platforms. +`bundle exec kitchen list` will output the list of test suites to be run aginst supported platforms. + +Cloud CI is done with the help of `travis`. `travis` handles multiple environments: - `Docker`-based jobs or so-called 'integration tests', these tests create a local release, install it with the package manager and then run unit-tests and system checks - `OSX` jobs, which handle basic unit-tests on `OSX` - Native `travis` jobs, which handle basic unit-tests and stylechecks +### Running local ci-tests + +1. Install requied gems with `bundle install`. +2. Run ci-tests with `bundle exec kitchen verify --test-base-path="$PWD/.ci-tests/integration"` + ### Release process The release process is defined in the `git`-hooks and `.travis.yml`. diff --git a/Gemfile b/Gemfile new file mode 100644 index 00000000..fef6d20e --- /dev/null +++ b/Gemfile @@ -0,0 +1,7 @@ +source 'https://rubygems.org' + +gem 'test-kitchen' +gem 'serverspec' +gem 'kitchen-ansible' +gem 'kitchen-docker' +gem 'kitchen-verifier-serverspec' diff --git a/man/man1/git-secret-hide.1 b/man/man1/git-secret-hide.1 index 8e2764e5..cd5f4884 100644 Binary files a/man/man1/git-secret-hide.1 and b/man/man1/git-secret-hide.1 differ diff --git a/man/man1/git-secret-hide.1.ronn b/man/man1/git-secret-hide.1.ronn index a4bf455f..fe9475bf 100644 --- a/man/man1/git-secret-hide.1.ronn +++ b/man/man1/git-secret-hide.1.ronn @@ -17,6 +17,7 @@ It is possible to modify the names of the encrypted files by setting `SECRETS_EX -v - verbose, shows extra information. -c - deletes encrypted files before creating new ones. -d - deletes unencrypted files after encryption. + -m - encrypt files only when modified. -h - shows help. diff --git a/src/_utils/_git_secret_tools.sh b/src/_utils/_git_secret_tools.sh index c46cc7c8..896fa20a 100644 --- a/src/_utils/_git_secret_tools.sh +++ b/src/_utils/_git_secret_tools.sh @@ -15,6 +15,76 @@ _SECRETS_DIR_PATHS_MAPPING="${_SECRETS_DIR_PATHS}/mapping.cfg" # Commands: : "${SECRETS_GPG_COMMAND:="gpg"}" +: "${SECRETS_CHECKSUM_COMMAND:="sha256sum"}" + + +# AWK scripts: +# shellcheck disable=2016 +AWK_FSDB_HAS_RECORD=' +BEGIN { FS=":"; OFS=":"; cnt=0; } +{ + if ( key == $1 ) + { + cnt++ + } +} +END { if ( cnt > 0 ) print "0"; else print "1"; } +' + +# shellcheck disable=2016 +AWK_FSDB_RM_RECORD=' +BEGIN { FS=":"; OFS=":"; } +{ + if ( key != $1 ) + { + print $1,$2; + } +} +' + +# shellcheck disable=2016 +AWK_FSDB_CLEAR_HASHES=' +BEGIN { FS=":"; OFS=":"; } +{ + print $1,""; +} +' + +# shellcheck disable=2016 +AWK_GPG_VER_CHECK=' +/^gpg/{ + version=$3 + n=split(version,array,".") + if( n >= 2) { + if(array[1] >= 2) + { + if(array[2] >= 1) + { + print 1 + } + else + { + print 0 + } + } + else + { + print 0 + } + } + else if(array[1] >= 2) + { + print 1 + } + else + { + print 0 + } +} +' + +# This is 1 for gpg vesion 2.1 or greater, otherwise 0 +GPG_VER_21="$(gpg --version | gawk "$AWK_GPG_VER_CHECK")" # Bash: @@ -129,6 +199,57 @@ function _unique_filename { } +# File System Database (fsdb): + + +function _get_record_filename { + # Returns 1st field from passed record + local record="$1" + local filename + filename=$(echo "$record" | awk -F: '{print $1}') + + echo "$filename" +} + + +function _get_record_hash { + # Returns 2nd field from passed record + local record="$1" + local hash + hash=$(echo "$record" | awk -F: '{print $2}') + + echo "$hash" +} + + +function _fsdb_has_record { + # First parameter is the key + # Second is the fsdb + local key="$1" # required + local fsdb="$2" # required + + # 0 on contains, 1 for error. + gawk -v key="$key" "$AWK_FSDB_HAS_RECORD" "$fsdb" +} + + +function _fsdb_rm_record { + # First parameter is the key (filename) + # Second is the path to fsdb + local key="$1" # required + local fsdb="$2" # required + + gawk -i inplace -v key="$key" "$AWK_FSDB_RM_RECORD" "$fsdb" +} + +function _fsdb_clear_hashes { + # First parameter is the path to fsdb + local fsdb="$1" # required + + gawk -i inplace "$AWK_FSDB_CLEAR_HASHES" "$fsdb" +} + + # Manuals: function _show_manual_for { @@ -315,7 +436,7 @@ function _list_all_added_files { fi while read -r line; do - echo "$line" + _get_record_filename "$line" done < "$path_mappings" } @@ -445,6 +566,10 @@ function _decrypt { base="$base --homedir=$homedir" fi + if [[ "$GPG_VER_21" -eq 1 ]]; then + base="$base --pinentry-mode loopback" + fi + if [[ ! -z "$passphrase" ]]; then echo "$passphrase" | $base --quiet --batch --yes --no-tty --passphrase-fd 0 \ "$encrypted_filename" diff --git a/src/commands/git_secret_add.sh b/src/commands/git_secret_add.sh index d968a8e1..1f70d560 100644 --- a/src/commands/git_secret_add.sh +++ b/src/commands/git_secret_add.sh @@ -69,18 +69,20 @@ function add { # Adding files to path mappings: - local path_mappings - path_mappings=$(_get_secrets_dir_paths_mapping) + local fsdb + fsdb=$(_get_secrets_dir_paths_mapping) for item in "${items[@]}"; do local path + local key path=$(_git_normalize_filename "$item") + key="$path" # Adding files into system, skipping duplicates. local already_in - already_in=$(_file_has_line "$path" "$path_mappings") + already_in=$(_fsdb_has_record "$key" "$fsdb") if [[ "$already_in" -eq 1 ]]; then - echo "$path" >> "$path_mappings" + echo "$key" >> "$fsdb" fi done diff --git a/src/commands/git_secret_hide.sh b/src/commands/git_secret_hide.sh index 88120808..9a1e3ab9 100644 --- a/src/commands/git_secret_hide.sh +++ b/src/commands/git_secret_hide.sh @@ -1,5 +1,19 @@ #!/usr/bin/env bash +# shellcheck disable=2016 +AWK_FSDB_UPDATE_HASH=' +BEGIN { FS=":"; OFS=":"; } +{ + if ( key == $1 ) + { + print key,hash; + } + else + { + print $1,$2; + } +} +' function _optional_clean { local clean="$1" @@ -26,7 +40,9 @@ function _optional_delete { while read -r line; do # So the formating would not be repeated several times here: - _find_and_clean "*$line" "$verbose" + local filename + filename=$(_get_record_filename "$line") + _find_and_clean "*$filename" "$verbose" done < "$path_mappings" if [[ ! -z "$verbose" ]]; then @@ -35,20 +51,49 @@ function _optional_delete { fi } +function _get_checksum_local { + local checksum="$SECRETS_CHECKSUM_COMMAND" + echo "$checksum" +} + +function _get_file_hash { + local input_path="$1" # Required + local checksum_local + local file_hash + + checksum_local="$(_get_checksum_local)" + file_hash=$($checksum_local "$input_path" | awk '{print $1}') + + echo "$file_hash" +} + +function _optional_fsdb_update_hash { + local key="$1" + local hash="$2" + local fsdb # path_mappings + + fsdb=$(_get_secrets_dir_paths_mapping) + + gawk -i inplace -v key="$key" -v hash="$hash" "$AWK_FSDB_UPDATE_HASH" "$fsdb" +} + function hide { local clean=0 local delete=0 + local fsdb_update_hash=0 # add checksum hashes to fsdb local verbose='' OPTIND=1 - while getopts 'cdvh' opt; do + while getopts 'cdmvh' opt; do case "$opt" in c) clean=1;; d) delete=1;; + m) fsdb_update_hash=1;; + v) verbose='v';; h) _show_manual_for 'hide';; @@ -71,9 +116,13 @@ function hide { path_mappings=$(_get_secrets_dir_paths_mapping) local counter=0 - while read -r line; do + while read -r record; do + local filename + local fsdb_file_hash local encrypted_filename - encrypted_filename=$(_get_encrypted_filename "$line") + filename=$(_get_record_filename "$record") + fsdb_file_hash=$(_get_record_hash "$record") + encrypted_filename=$(_get_encrypted_filename "$filename") local recipients recipients=$(_get_recepients) @@ -83,13 +132,23 @@ function hide { local input_path local output_path - input_path=$(_append_root_path "$line") + input_path=$(_append_root_path "$filename") output_path=$(_append_root_path "$encrypted_filename") - # shellcheck disable=2086 - $gpg_local --use-agent --yes --trust-model=always --encrypt \ - $recipients -o "$output_path" "$input_path" + file_hash=$(_get_file_hash "$input_path") + # encrypt file only if required + if [[ "$fsdb_file_hash" != "$file_hash" ]]; then + # shellcheck disable=2086 + $gpg_local --use-agent --yes --trust-model=always --encrypt \ + $recipients -o "$output_path" "$input_path" > /dev/null 2>&1 + # If -m option was provided, it will update unencrypted file hash + local key="$filename" + local hash="$file_hash" + # Update file hash if required in fsdb + [[ "$fsdb_update_hash" -gt 0 ]] && \ + _optional_fsdb_update_hash "$key" "$hash" + fi counter=$((counter+1)) done < "$path_mappings" diff --git a/src/commands/git_secret_init.sh b/src/commands/git_secret_init.sh index f2fe5819..e3c64885 100644 --- a/src/commands/git_secret_init.sh +++ b/src/commands/git_secret_init.sh @@ -1,5 +1,25 @@ #!/usr/bin/env bash +# shellcheck disable=2016 +AWK_ADD_TO_GITIGNORE=' +BEGIN { cnt=0; } +{ + print $0 + if ( $0 == pattern ) cnt++; +} +ENDFILE { if ( cnt == 0) print pattern; } +' + +function gitignore_add_pattern { + local pattern + local gitignore_file_path + + pattern="$1" + gitignore_file_path=$(_append_root_path '.gitignore') + + _maybe_create_gitignore + gawk -i inplace -v pattern="$pattern" "$AWK_ADD_TO_GITIGNORE" "$gitignore_file_path" +} function init { OPTIND=1 @@ -30,4 +50,10 @@ function init { touch "$(_get_secrets_dir_keys_mapping)" "$(_get_secrets_dir_paths_mapping)" echo "'$git_secret_dir/' created." + + local random_seed_file + random_seed_file=".gitsecret/keys/random_seed" + gitignore_add_pattern "$random_seed_file" + + # TODO: git attributes to view diffs } diff --git a/src/commands/git_secret_remove.sh b/src/commands/git_secret_remove.sh index 3fc44563..2afeb86b 100644 --- a/src/commands/git_secret_remove.sh +++ b/src/commands/git_secret_remove.sh @@ -39,7 +39,13 @@ function remove { fi # Deleting it from path mappings: - _delete_line "$normalized_path" "$path_mappings" + # _delete_line "$normalized_path" "$path_mappings" + # Remove record from fsdb with matching key + local key + key="$normalized_path" + fsdb="$path_mappings" + _fsdb_rm_record "$key" "$fsdb" + rm -f "${path_mappings}.bak" # not all systems create '.bak' # Optional clean: diff --git a/src/commands/git_secret_reveal.sh b/src/commands/git_secret_reveal.sh index cc1131df..7f816467 100644 --- a/src/commands/git_secret_reveal.sh +++ b/src/commands/git_secret_reveal.sh @@ -32,8 +32,10 @@ function reveal { local counter=0 while read -r line; do + local filename local path - path=$(_append_root_path "$line") + filename=$(_get_record_filename "$line") + path=$(_append_root_path "$filename") # The parameters are: filename, write-to-file, force, homedir, passphrase _decrypt "$path" "1" "$force" "$homedir" "$passphrase" diff --git a/src/commands/git_secret_tell.sh b/src/commands/git_secret_tell.sh index e082f2a5..ecdd83b6 100644 --- a/src/commands/git_secret_tell.sh +++ b/src/commands/git_secret_tell.sh @@ -1,5 +1,17 @@ #!/usr/bin/env bash +# shellcheck disable=2016 +AWK_GPG_KEY_CNT=' +BEGIN { cnt=0; OFS=":"; FS=":"; } +flag=0; $1 == "pub" { cnt++ } +END { print cnt } +' + +function get_gpg_key_count { + local gpg_local + gpg_local=$(_get_gpg_local) + $gpg_local --list-public-keys --with-colon | gawk "$AWK_GPG_KEY_CNT" +} function tell { local emails @@ -46,6 +58,8 @@ function tell { _abort "you must provide at least one email address." fi + local start_key_cnt + start_key_cnt=$(get_gpg_key_count) for email in "${emails[@]}"; do # This file will be removed automatically: _temporary_file # note, that `_temporary_file` will export `filename` var. @@ -71,4 +85,11 @@ function tell { done echo "done. ${emails[*]} added as someone who know(s) the secret." + + # force re-encrypting of files if required + local fsdb + local end_key_cnt + fsdb=$(_get_secrets_dir_paths_mapping) + end_key_cnt=$(get_gpg_key_count) + [[ $start_key_cnt -ne $end_key_cnt ]] && _fsdb_clear_hashes "$fsdb" } diff --git a/tests/_test_base.bash b/tests/_test_base.bash index b8dfbb5c..22b64ab2 100644 --- a/tests/_test_base.bash +++ b/tests/_test_base.bash @@ -13,11 +13,22 @@ FIXTURES_DIR="$BATS_TEST_DIRNAME/fixtures" TEST_GPG_HOMEDIR="$BATS_TMPDIR" +AWK_GPG_GET_FP=' +BEGIN { OFS=":"; FS=":"; } +{ + if ( $1 == "fpr" ) + { + print $10 + exit + } +} +' + # GPG-based stuff: : "${SECRETS_GPG_COMMAND:="gpg"}" # This command is used with absolute homedir set and disabled warnings: -GPGTEST="$SECRETS_GPG_COMMAND --homedir=$TEST_GPG_HOMEDIR --no-permission-warning" +GPGTEST="$SECRETS_GPG_COMMAND --homedir=$TEST_GPG_HOMEDIR --no-permission-warning --batch" # Personal data: @@ -40,6 +51,23 @@ function test_user_email { # GPG: +function stop_gpg_agent { + local username=$(id -u -n) + ps awx -u "$username" | gawk \ + '/gpg-agent --homedir/ { if ( $0 !~ "awk" ) { system("kill -9 "$1) } }' \ + > /dev/null 2>&1 +} + + +function get_gpgtest_prefix { + if [[ $GPG_VER_21 -eq 1 ]]; then + echo "echo \"$(test_user_password $1)\" | " + else + echo "" + fi +} + + function get_gpg_fingerprint_by_email { local email="$1" local fingerprint @@ -54,13 +82,8 @@ function get_gpg_fingerprint_by_email { function install_fixture_key { local public_key="$BATS_TMPDIR/public-${1}.key" - local email - email=$(test_user_email "$1") - - $SECRETS_GPG_COMMAND --homedir="$FIXTURES_DIR/gpg/${1}" \ - --no-permission-warning --output "$public_key" \ - --armor --batch --yes --export "$email" > /dev/null 2>&1 + \cp "$FIXTURES_DIR/gpg/${1}/public.key" "$public_key" $GPGTEST --import "$public_key" > /dev/null 2>&1 rm -f "$public_key" } @@ -68,26 +91,27 @@ function install_fixture_key { function install_fixture_full_key { local private_key="$BATS_TMPDIR/private-${1}.key" + local gpgtest_prefix="$(get_gpgtest_prefix $1)" + local gpgtest_import="$gpgtest_prefix $GPGTEST" local email local fp local fingerprint email=$(test_user_email "$1") - $SECRETS_GPG_COMMAND --homedir="$FIXTURES_DIR/gpg/${1}" \ - --no-permission-warning --output "$private_key" --armor \ - --yes --export-secret-key "$email" > /dev/null 2>&1 + \cp "$FIXTURES_DIR/gpg/${1}/private.key" "$private_key" - $GPGTEST --allow-secret-key-import \ - --import "$private_key" > /dev/null 2>&1 - - fp=$($GPGTEST --with-fingerprint "$private_key") + bash -c "$gpgtest_import --allow-secret-key-import \ + --import \"$private_key\"" > /dev/null 2>&1 # since 0.1.2 fingerprint is returned: - fingerprint=$(echo "$fp" | tr -d ' ' | sed -n '2p' | sed -e 's/.*=//g') + fingerprint=$($GPGTEST --with-fingerprint \ + --with-colon \ + --list-secret-key $email | gawk "$AWK_GPG_GET_FP") install_fixture_key "$1" + rm -f "$private_key" # return fingerprint to delete it later: echo "$fingerprint" } @@ -97,7 +121,7 @@ function uninstall_fixture_key { local email email=$(test_user_email "$1") - $GPGTEST --batch --yes --delete-key "$email" > /dev/null 2>&1 + $GPGTEST --yes --delete-key "$email" > /dev/null 2>&1 } @@ -111,7 +135,7 @@ function uninstall_fixture_full_key { fingerprint=$(get_gpg_fingerprint_by_email "$email") fi - $GPGTEST --batch --yes \ + $GPGTEST --yes \ --delete-secret-keys "$fingerprint" > /dev/null 2>&1 uninstall_fixture_key "$1" @@ -210,8 +234,13 @@ function unset_current_state { # unsets `git` state remove_git_repository + # stop gpg-agent + stop_gpg_agent + # removes gpg homedir: - rm -f "pubring.gpg" "pubring.gpg~" "secring.gpg" "trustdb.gpg" "random_seed" + find "$TEST_GPG_HOMEDIR" \ + -regex ".*\/random_seed\|.*\.gpg\|.*\.kbx.?\|.*private-keys.*\|.*test_sub_dir\|.*S.gpg-agent\|.*file_to_hide.*" \ + -exec rm -rf {} + # return to the base dir: cd "$SECRET_PROJECT_ROOT" || exit 1 diff --git a/tests/fixtures/gpg/attacker1/private.key b/tests/fixtures/gpg/attacker1/private.key new file mode 100644 index 00000000..678a5e95 --- /dev/null +++ b/tests/fixtures/gpg/attacker1/private.key @@ -0,0 +1,59 @@ +-----BEGIN PGP PRIVATE KEY BLOCK----- +Version: GnuPG v1 + +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 +0Vjcr8GgU7JyYnSqF2Ua8YA6 +=Ygfi +-----END PGP PRIVATE KEY BLOCK----- diff --git a/tests/fixtures/gpg/attacker1/public.key b/tests/fixtures/gpg/attacker1/public.key new file mode 100644 index 00000000..6b367947 --- /dev/null +++ b/tests/fixtures/gpg/attacker1/public.key @@ -0,0 +1,30 @@ +-----BEGIN PGP PUBLIC KEY BLOCK----- +Version: GnuPG v1 + +mQENBFaigVQBCADC5dJ0xweZ+6L0owo2wpKSbQFGQoRJxYVcc1dWe3zNZ5yBrJDV +N79rYV5AmHnIGDAJrHHV9rYM4+C8obKka7P3ROm0RMsYKDhpQXWFjsOrl1rjWL86 +6D4X7Q5uuJWluPp1+hbzpBmNCX3Y5sr1fmCazvR5iIAvY3EkYbqDt2+BtGTqlevY +ivWiOoPKRY9Dc44rKQh8GmaVJzcO3D21IF70i3GnOtjUSK8DWXdD4BrtYTE/9Ua4 +bmT2pOPmGMcI38pQHZQXqMPTzloakZk9qIbBoB3FS/UFxQr3R3V+tXPm1Eca/75G ++U4VCRLUFWsDU5d+oTCFCa0qNjGnLFOE85C7ABEBAAG0ImF0dGFja2VyMSA8YXR0 +YWNrZXIxQGdpdHNlY3JldC5pbz6JATgEEwECACIFAlaigVQCGwMGCwkIBwMCBhUI +AgkKCwQWAgMBAh4BAheAAAoJEIgBAzFTzCCldUcIALEAEJo7Q6cikv/s8xYFbjqr +uUH36spRTF8PM63IYgS03kwhCqIsTY+XHHKQBvcQ1GXDMDMP5UgM9TF0n0Ohhr5e +BK5Wa5cfUkmnKj8AzaCljHIvTw29yaWl2bUEAqw5sJ2aUhOmyr4QKEyGgOk5/IOL +jqN708g7l9Q8563FBazAlu78Oc7bbQNYb4OYh67OHYmvxWkV9Ejn/cv9LvZEFtqZ +FpVS9qUYEGmMB5exUERp68Im8chKU0PMfnfLlPOwzWmolGeRnLGU9lOnJobs/5NC +BRi+NPIbheYedClRU2EDUHNy3t7/cK4fPDm5+HIl/9mIs3nw6OVhref5r5VH6e+5 +AQ0EVqKBVAEIAL+eDpF/Z9Pi/+fVFFlras/rIgRd6N8DFNACqAEyGW4pcaDjx877 +/IlqUpUoUzbGOB6rGX+7SKnyS6vdRIoFdLkLNL+s8MxQt9bfJUGkMtINLr9OMZzC +L2MOMUYVGu3QaYaJHrrkglO7ic6us2tyGtYaDWRH3ZRBv9S3RjMzC1EcVJVlsKc0 +SXTxKRHevyJ2rzYn34hmoiV301EH6YnM9JO3sl4CuT2rdO1GiFvNIKJfn4IbuAYR +BwFgHwFeqHHf2H1J+x2seeZdP56Qt2O9iTIYUltdR4DhNYs99yDRhfaXzS/lUMEI +/YFEAjnHM6rg+DUO0YEAHWUNivZOHGjs28UAEQEAAYkBHwQYAQIACQUCVqKBVAIb +DAAKCRCIAQMxU8wgpQqeCACBDi7KrqQzdzeipLadUsaTptvFBlwavpCLRtNbJI8v +5i4kr8cLmyqGAwCS8Yem3SCI/K4ujln8an6XrhsOE/uwfyQz5iUcP7BN9sIEp/IT +OIXu0q0kzxThmpJqHzvfbvkPemFEiwYwGZn87cFXmd7FMEoFIt/s/bCnPCuBkxvU +Mj/D65Sb5x1X+FzWjK2mOVJGpTHAixns+DDHOfXEkghQTfj1pX/LBV9nXKlSZtpD +O/p/kx+xITxXA/a4EDtD2JpZBYmSTcbyVamQEMTzMIfEUhMbSrhKRYcm6g5Jbu5o +y0ci/5qIhsR45pA7JSc00Vjcr8GgU7JyYnSqF2Ua8YA6 +=CU3L +-----END PGP PUBLIC KEY BLOCK----- diff --git a/tests/fixtures/gpg/attacker1/pubring.gpg b/tests/fixtures/gpg/attacker1/pubring.gpg deleted file mode 100755 index ca28e4cb..00000000 Binary files a/tests/fixtures/gpg/attacker1/pubring.gpg and /dev/null differ diff --git a/tests/fixtures/gpg/attacker1/pubring.gpg~ b/tests/fixtures/gpg/attacker1/pubring.gpg~ deleted file mode 100755 index cef7514e..00000000 Binary files a/tests/fixtures/gpg/attacker1/pubring.gpg~ and /dev/null differ diff --git a/tests/fixtures/gpg/attacker1/random_seed b/tests/fixtures/gpg/attacker1/random_seed deleted file mode 100755 index 885dc50f..00000000 Binary files a/tests/fixtures/gpg/attacker1/random_seed and /dev/null differ diff --git a/tests/fixtures/gpg/attacker1/secring.gpg b/tests/fixtures/gpg/attacker1/secring.gpg deleted file mode 100755 index 0d68730d..00000000 Binary files a/tests/fixtures/gpg/attacker1/secring.gpg and /dev/null differ diff --git a/tests/fixtures/gpg/attacker1/trustdb.gpg b/tests/fixtures/gpg/attacker1/trustdb.gpg deleted file mode 100755 index f1b041e7..00000000 Binary files a/tests/fixtures/gpg/attacker1/trustdb.gpg and /dev/null differ diff --git a/tests/fixtures/gpg/user1/private.key b/tests/fixtures/gpg/user1/private.key new file mode 100644 index 00000000..1a412fe9 --- /dev/null +++ b/tests/fixtures/gpg/user1/private.key @@ -0,0 +1,59 @@ +-----BEGIN PGP PRIVATE KEY BLOCK----- +Version: GnuPG v1 + +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 +Bh9SiS8oRa1I+f4= +=PunG +-----END PGP PRIVATE KEY BLOCK----- diff --git a/tests/fixtures/gpg/user1/public.key b/tests/fixtures/gpg/user1/public.key new file mode 100644 index 00000000..3d5358c2 --- /dev/null +++ b/tests/fixtures/gpg/user1/public.key @@ -0,0 +1,30 @@ +-----BEGIN PGP PUBLIC KEY BLOCK----- +Version: GnuPG v1 + +mQENBFaigO0BCACwtBp5eg1d68f9WhmYew/4eU5zjaJsNj1DHsHokxsUt9QpIdVq +DuPxlW8pTOUrhqQZd0ozaaDMswwFpzkblelQJzt/juqy/lkK2StlQfK2YRk7zehV +HA6YOtTFyYbyheCeSFNJ4bfy3nn1lSDTtSmDpQBz19hVBP9JapI8K96nTSuK0NAb +FEZ7ZdFLdXbtEkXHtTL+eqrys8UI7Ou+iZZ+dBlwTl9Jszg/b6IjYCYFT/LKuLX3 +ss9fI/ypuwjB+1zys9WNDiNrrb8e26GDeOjfTH0vPuV9nU2gqLVzlssTLiWkrjSW +g3OhO3jBBa59oEf60eBreL0FZ74LqRsPT8NVABEBAAG0GnVzZXIxIDx1c2VyMUBn +aXRzZWNyZXQuaW8+iQE4BBMBAgAiBQJWooDtAhsDBgsJCAcDAgYVCAIJCgsEFgID +AQIeAQIXgAAKCRDSgFpBgumf9H7JB/0SGchHccPND6sjUVYO/cK4bret8u6L7Hmr +6jesKRAoJCuLq6lTQRK8wNS6hEDjRi1I3IErQnUhgGCZcOWSeuyu6EYnczg52aLy +53U+A9VmJH+L+I55feQm5SVJD0jByp8vrsNDK4Jd0Cq4uQcQYIDB7t99HILYaclA +tD/sqotWER3Xvtj9dOyHZKS2ICdaic95aAIJugJhtJMIiusCGc2yML5xLWQ1cb6H +6zNaOZQF4B/qbscgu5WWlPIJyalxjOa2CQBDwtxOjJuOX9yZBI523ea7idO0kCdA +xpJShii+c0xtJV99DG9vBF19DgCtTDgyB73dy3Eqm1SepTF1CXoSuQENBFaigO0B +CADag/bxqEeudSnZ9M9BTlZEoGUBuNyrV7KI9Inwv3gufCaj4UQkxXEi2+eQCBi7 +AB3LvskcJEsAaworEyB6jteXUm2G24/tS32F9JTgTbRhF2QODWdNoRjprAtjQ+Pt +akOWnwSIw5THeXHkGNzIqXVh59JouQhdOImiw5jDxIsuguzSqH7krPuPpMs4OPUX +Z4z/znuHCLIhHuAegrzD65zqDl8jHJOg5mc/x4/PqZHhofr2k9/7G08gqzhD5mgv +h5i39owsnK+sMVZDo8BGNVdWYVVYvtu7jdhbJJhCZqnkIbA4cCoai1pns/ZFgM/U +26gFQeROcmrSTJsXOqXCJG6RABEBAAGJAR8EGAECAAkFAlaigO0CGwwACgkQ0oBa +QYLpn/QNjQf8DXiS/dKXQIFSQCfpe1+wS90ErJ45mM82UrUfOA3A8KRuk5HiD2ZO +oDi2v9fOkmT8DZUTnLT8MhpGfGK/L22ueNAbt413KabTwzL4ZEI9Y6Rx4iVJXsgF +mHaIy9ikVVcQs5yMfrGV1z5FCInSKtFezbxdtdhztPglhmvvGANAhvrLJoAB13r/ ++TWgcZB/a5Ow1ZnOzjc4EA3bN7cN1hZcy2yyQdW+ecUlIBH7TeuD3ZUxIB+HoYqr +RoUXXapNQABZUSSgAUeBEFBGpUVP1GAo6CTtVGXK07Wy/ls/lmW8Tki830cJMcs5 +gKv+xOA5vehhhD/NkCYGH1KJLyhFrUj5/g== +=0Q64 +-----END PGP PUBLIC KEY BLOCK----- diff --git a/tests/fixtures/gpg/user1/pubring.gpg b/tests/fixtures/gpg/user1/pubring.gpg deleted file mode 100755 index 09d8348d..00000000 Binary files a/tests/fixtures/gpg/user1/pubring.gpg and /dev/null differ diff --git a/tests/fixtures/gpg/user1/pubring.gpg~ b/tests/fixtures/gpg/user1/pubring.gpg~ deleted file mode 100755 index f662a8ec..00000000 Binary files a/tests/fixtures/gpg/user1/pubring.gpg~ and /dev/null differ diff --git a/tests/fixtures/gpg/user1/random_seed b/tests/fixtures/gpg/user1/random_seed deleted file mode 100755 index a81b0039..00000000 Binary files a/tests/fixtures/gpg/user1/random_seed and /dev/null differ diff --git a/tests/fixtures/gpg/user1/secring.gpg b/tests/fixtures/gpg/user1/secring.gpg deleted file mode 100755 index c377cc72..00000000 Binary files a/tests/fixtures/gpg/user1/secring.gpg and /dev/null differ diff --git a/tests/fixtures/gpg/user1/trustdb.gpg b/tests/fixtures/gpg/user1/trustdb.gpg deleted file mode 100755 index 92e8847c..00000000 Binary files a/tests/fixtures/gpg/user1/trustdb.gpg and /dev/null differ diff --git a/tests/fixtures/gpg/user2/private.key b/tests/fixtures/gpg/user2/private.key new file mode 100644 index 00000000..30afe973 --- /dev/null +++ b/tests/fixtures/gpg/user2/private.key @@ -0,0 +1,59 @@ +-----BEGIN PGP PRIVATE KEY BLOCK----- +Version: GnuPG v1 + +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 +FfGupHnbRtqsqQ== +=7tcw +-----END PGP PRIVATE KEY BLOCK----- diff --git a/tests/fixtures/gpg/user2/public.key b/tests/fixtures/gpg/user2/public.key new file mode 100644 index 00000000..9ab5b183 --- /dev/null +++ b/tests/fixtures/gpg/user2/public.key @@ -0,0 +1,30 @@ +-----BEGIN PGP PUBLIC KEY BLOCK----- +Version: GnuPG v1 + +mQENBFaigRUBCACgb+7xhV1nJZim3noxozslfrWXPYEVQt7Is8QjATaKg6ULqImi +tpgnlUNCaEAd3PMufVSqd416KyytwUOBVaFIEej/SJcJ2UU4nFvJsvo4bNmInOc3 +cNSqJ5VcI7D++wdHSecr2YayWtsh85jt6xI2oGBN334Yl6sHnNGC/vmE0pWovpib +rwAW7bWSOYOQxpzANm9O+9oJ6WsTGVVWkZ/SAaRo+VYDA5rwCI6STt+rEcKalr5C +sbtqELDDDrYYviU4kZx6WYdiDcF5ATSiuGZrQTjEdBFc+GmFxbW+aumeC+Y1jYOp +aYUhbDKffnrxvFjm5+3PBbrPmJ5rFWr1f00bABEBAAG0GnVzZXIyIDx1c2VyMkBn +aXRzZWNyZXQuaW8+iQE4BBMBAgAiBQJWooEVAhsDBgsJCAcDAgYVCAIJCgsEFgID +AQIeAQIXgAAKCRDqoOTrazNsiz97CACLgvaQgkS2oLRlQUZX0Yma+P+C4TJjlu5Q +pVdQyk13w2Fn25EsEWYbrya2MiU3y3A25xdRM7aUtZiEwmlSGOht1E/PDzzus2qz +BIilZq89mt4wqBcnvb/aZ32btyv0WYRn19nHzS0HB0vb5xhrUiLG6ja+TZSfQsPj +aoJuHSdHFIN/eDrIO1IdhniLojz1fADlNIbX8LS4hytEoYMGSF3TmyoIn23+bqgD +GTcDydkz6La5LT52Y5XACYO/r8Drj4B9/mFizHztR4B1TvqeLevDSlldOf3TC/9p +jR16JwOWZJRq21I2D8boqgTpEREvjuK3JTTsPjJS9MEYvmBW94FfuQENBFaigRUB +CAC0PMNd0lI7CYOP8mECTTAP5EGPEjM79X8VcKi0dqqJJJG9nQmfoIysZrQQqSwZ +eOpjr6OEL8ctv2FeNH5yJT8TrghU0l20anvuuNVTKCuxjR/RlRJC59ML2VxUA/zA +3Hn0GTSeW47TN4fSUxFT9wt3IYKzsLeh07nFW8WXkgnqMf/3nLoF1EZIM1OfN5Bd +P59QfEtls8boBsshcM4ArY4AedRjra4YsXyXr3HUfKYtWoP1NhNT1Wlir0iXx7Xw +7p+oTUwSnjMeTJN/oi8KBms4Uv5cCnAdjLU2yQqL1Y0N1AK+kOq81I9lKqtqNN14 +ng3O5WKn5xwNP+1lVMDwD7RpABEBAAGJAR8EGAECAAkFAlaigRUCGwwACgkQ6qDk +62szbIvUZQf/adIYw+fHM1zlGJH+C/lEFoGi0AXOTqBH13T+haoykwrxnBOdaTGY +196bj+uiSbtFqQWcuMNrOWNNH6NAl30Ujya/ltLv7FJ3DOuUyIU/3Bhp1t1+jEpp +MJRYk2pkRmmTg2lrOgSvPiqNgmK/FBx3t+JCtmQxtrTBBnJcmx5/8YGdOCEsiGJ2 +jl+5Im4XgT0OhQX320o82XrK7/Pp+ttmc7ExT6pc53sSYRUfEyObpCYVIz1nWK1F +ujfW+ojFFUvhHPwSL3nydkJORg8lcQm/zXjbgCeMZ/l3ynkvSA+X9/Q7aQWGrpU0 +LRLGAeA9PZZDYx9JTQUYFfGupHnbRtqsqQ== +=HLsH +-----END PGP PUBLIC KEY BLOCK----- diff --git a/tests/fixtures/gpg/user2/pubring.gpg b/tests/fixtures/gpg/user2/pubring.gpg deleted file mode 100755 index 4205f575..00000000 Binary files a/tests/fixtures/gpg/user2/pubring.gpg and /dev/null differ diff --git a/tests/fixtures/gpg/user2/pubring.gpg~ b/tests/fixtures/gpg/user2/pubring.gpg~ deleted file mode 100755 index a91b44b9..00000000 Binary files a/tests/fixtures/gpg/user2/pubring.gpg~ and /dev/null differ diff --git a/tests/fixtures/gpg/user2/random_seed b/tests/fixtures/gpg/user2/random_seed deleted file mode 100755 index d7dcb1b6..00000000 Binary files a/tests/fixtures/gpg/user2/random_seed and /dev/null differ diff --git a/tests/fixtures/gpg/user2/secring.gpg b/tests/fixtures/gpg/user2/secring.gpg deleted file mode 100755 index 79c030b5..00000000 Binary files a/tests/fixtures/gpg/user2/secring.gpg and /dev/null differ diff --git a/tests/fixtures/gpg/user2/trustdb.gpg b/tests/fixtures/gpg/user2/trustdb.gpg deleted file mode 100755 index 1fdf84e1..00000000 Binary files a/tests/fixtures/gpg/user2/trustdb.gpg and /dev/null differ diff --git a/tests/test_usage.bats b/tests/test_usage.bats index aff26b31..309e8d96 100644 --- a/tests/test_usage.bats +++ b/tests/test_usage.bats @@ -29,7 +29,7 @@ function teardown { @test "run 'usage' with ignored '.gitsecret/'" { - echo ".gitsecret/" >> ".gitignore" + echo ".gitsecret" >> ".gitignore" run git secret usage [ "$status" -eq 1 ]