├── README.md ├── LICENSE └── passed /README.md: -------------------------------------------------------------------------------- 1 | # Passed 2 | 3 | A simple script to modify password store entries with sed commands 4 | 5 | ## Installation 6 | 7 | ### ArchLinux 8 | 9 | Get passed-git with your favorite aur helper 10 | 11 | ### Other systems 12 | 13 | Copy passed from this repo somewhere in your path. 14 | 15 | #### Dependencies: 16 | 17 | - [pass](https://github.com/zx2c4/password-store) 18 | - [ruby](https://ruby-lang.org) 19 | 20 | ## Usage 21 | 22 | run `passed ` 23 | 24 | ### Example: 25 | 26 | To change `UserName` to `user` in your pass entries run `passed 27 | 's/UserName/user/'` 28 | 29 | Passed will ask you to confirm each overwrite. If you know what you're doing 30 | you can pipe `yes` to the passed command. 31 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2015 jreinert 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | 23 | -------------------------------------------------------------------------------- /passed: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | 3 | abort("usage: #{$PROGRAM_NAME} ") if ARGV.empty? 4 | 5 | sed_command = ['sed', *ARGV] 6 | PASS_DIR = ENV['PASSWORD_STORE_DIR'] || "#{ENV['HOME']}/.password-store" 7 | 8 | def keys(dir) 9 | key_file = "#{dir}/.gpg-id" 10 | return unless File.exist?(key_file) 11 | File.read(key_file).lines.map(&:chomp) 12 | end 13 | 14 | def each_entry_with_key(dir = PASS_DIR, keys = nil, &block) 15 | keys = keys(dir) || keys 16 | fail('no encryption keys found') unless keys 17 | Dir[File.join(dir, '{,.}**', '{,.}*.gpg')].each { |entry| yield(entry, keys) } 18 | end 19 | 20 | each_entry_with_key do |entry, keys| 21 | new_content = nil 22 | IO.popen(['gpg', '--batch', '-q', '-d', entry]) do |gpg| 23 | IO.popen(sed_command, 'w+') do |sed| 24 | sed.write gpg.read 25 | sed.close_write 26 | new_content = sed.read 27 | end 28 | end 29 | 30 | puts entry 31 | puts new_content 32 | puts 'overwrite? (y/N)' 33 | answer = STDIN.gets 34 | next unless answer && answer.chomp =~ /^y/i 35 | 36 | recipients = keys.map { |key| ['-r', key] }.flatten 37 | File.delete(entry) 38 | encrypt_cmd = ['gpg', '--batch', '-q', '-e', '-o', entry, *recipients] 39 | IO.popen(encrypt_cmd, 'w+') do |gpg| 40 | gpg.write(new_content) 41 | end 42 | end 43 | --------------------------------------------------------------------------------