keepassxc 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/README.md +41 -0
- data/exe/keepassxc-rb +17 -0
- data/keepassxc.gemspec +24 -0
- data/lib/keepassxc.rb +14 -0
- data/lib/keepassxc/client.rb +100 -0
- data/lib/keepassxc/helper.rb +11 -0
- data/lib/keepassxc/key_store.rb +50 -0
- data/lib/keepassxc/version.rb +3 -0
- metadata +54 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 6c60203ef5b9cdcd3cbabce41a9712e62d35793cbc5f5a3cb40070a45acee25d
|
4
|
+
data.tar.gz: e23b41982c3bec59afff4a50230fa31e00172c51949749e9ac27d3477a94a434
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 8737d87a03efbcb532f225cee2eb22ead55449944fc0c5b53b366b8bf922a4fb8197834e4d520061e0bfca1bda19b634de87bedda13df56fb789ad4a8edc213c
|
7
|
+
data.tar.gz: a2be3cf5b98ed7e63c65097882b391dd3faef90d0ee3345b6389575412ce70770bb561d79e37f91bce162fb323682047ab247cea4bb72601776a3a7fd55dfaf7
|
data/README.md
ADDED
@@ -0,0 +1,41 @@
|
|
1
|
+
# KeypassXC Ruby binding
|
2
|
+
|
3
|
+
You want to fetch login data as the browsers do. Then this is for you.
|
4
|
+
Similar to my https://github.com/Kjarrigan/keepasshttp-ruby repo.
|
5
|
+
|
6
|
+
## Work in progress
|
7
|
+
|
8
|
+
A coworker just asked me wether I have use the keepassxc-cli but it requires
|
9
|
+
to enter a password every time which is annoying and then I remembered my
|
10
|
+
keepasshttp-ruby binding and it turns out this is no longer the desired way
|
11
|
+
for KeepassXC. So why not make the new version work. Yay!
|
12
|
+
|
13
|
+
## Links
|
14
|
+
|
15
|
+
Some things have changed but the rough idea is the same. So I can probably copy
|
16
|
+
over quite a bit of context.
|
17
|
+
|
18
|
+
* [My HTTP Code](https://github.com/Kjarrigan/keepasshttp-ruby/blob/master/lib/keepasshttp.rb)
|
19
|
+
* [The official protocal docs](https://github.com/keepassxreboot/keepassxc-browser/blob/develop/keepassxc-protocol.md)
|
20
|
+
|
21
|
+
## Basic communication snippet
|
22
|
+
|
23
|
+
It is already working now! Altough some comfort is still missing, you can already register your client and
|
24
|
+
fetch logins. Yay!
|
25
|
+
|
26
|
+
```ruby
|
27
|
+
load 'test.rb'
|
28
|
+
|
29
|
+
kpx = KeepassXC.new client_identifier: KEY_FROM_ASSOCIATE_OR_DB, client_name: ID_FROM_ASSOCIATE_OR_DB
|
30
|
+
kpx.change_public_keys
|
31
|
+
# kpx.associate
|
32
|
+
kpx.test_associate
|
33
|
+
p kpx.get_logins 'https://github.com'
|
34
|
+
```
|
35
|
+
|
36
|
+
You can check what clients are already registered in your DB via the GUI like this:
|
37
|
+
* Database
|
38
|
+
* Database-Settings
|
39
|
+
* Browser-Integration
|
40
|
+
|
41
|
+
Technically you could even re-use the Key/ID from your browser by just copying them from there.
|
data/exe/keepassxc-rb
ADDED
@@ -0,0 +1,17 @@
|
|
1
|
+
require 'keepassxc'
|
2
|
+
|
3
|
+
name = ARGV[1] || `hostname`.chomp
|
4
|
+
|
5
|
+
cfg = KeepassXC::KeyStore.find_or_create
|
6
|
+
kpx = KeepassXC::Client.new client_name: name
|
7
|
+
kpx.change_public_keys
|
8
|
+
if cfg.profiles[name]
|
9
|
+
kpx.client_identifier = cfg.profiles[name]
|
10
|
+
else
|
11
|
+
kpx.associate
|
12
|
+
cfg.profiles[name] = kpx.client_identifier
|
13
|
+
cfg.save
|
14
|
+
end
|
15
|
+
kpx.test_associate
|
16
|
+
|
17
|
+
puts kpx.get_logins(ARGV[0]).first['password']
|
data/keepassxc.gemspec
ADDED
@@ -0,0 +1,24 @@
|
|
1
|
+
require_relative 'lib/keepassxc/version'
|
2
|
+
|
3
|
+
Gem::Specification.new do |spec|
|
4
|
+
spec.name = 'keepassxc'
|
5
|
+
spec.version = KeepassXC::VERSION
|
6
|
+
spec.authors = ['Holger Arndt']
|
7
|
+
spec.email = ['keepassxc-ruby@kjarrigan.de']
|
8
|
+
|
9
|
+
spec.summary = %q{Ruby bindings for the KeepassXC Browser API}
|
10
|
+
spec.description = %q{Ruby bindings for the KeepassXC Browser API}
|
11
|
+
spec.homepage = 'https://github.com/Kjarrigan/keepassxc-ruby'
|
12
|
+
spec.required_ruby_version = Gem::Requirement.new('>= 2.7.0')
|
13
|
+
|
14
|
+
spec.metadata['homepage_uri'] = spec.homepage
|
15
|
+
spec.metadata['source_code_uri'] = spec.homepage
|
16
|
+
spec.metadata['changelog_uri'] = spec.homepage
|
17
|
+
|
18
|
+
spec.files = Dir.chdir(__dir__) do
|
19
|
+
`git ls-files`.split("\n").reject { |f| f.match(%r{^(test|spec|features)/}) }
|
20
|
+
end
|
21
|
+
spec.bindir = 'exe'
|
22
|
+
spec.executables = %w{keepassxc-rb}
|
23
|
+
spec.require_paths = ['lib']
|
24
|
+
end
|
data/lib/keepassxc.rb
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
require 'socket'
|
2
|
+
require 'json'
|
3
|
+
|
4
|
+
# TODO, replace this with openssl
|
5
|
+
require 'rbnacl'
|
6
|
+
|
7
|
+
module KeepassXC
|
8
|
+
class Error < StandardError; end
|
9
|
+
|
10
|
+
autoload :Client, 'keepassxc/client'
|
11
|
+
autoload :Helper, 'keepassxc/helper'
|
12
|
+
autoload :KeyStore, 'keepassxc/key_store'
|
13
|
+
autoload :VERSION, 'keepassxc/version'
|
14
|
+
end
|
@@ -0,0 +1,100 @@
|
|
1
|
+
require_relative 'helper'
|
2
|
+
|
3
|
+
module KeepassXC
|
4
|
+
class Client
|
5
|
+
include Helper
|
6
|
+
|
7
|
+
attr_accessor :client_id, :client_identifier, :client_name
|
8
|
+
|
9
|
+
def initialize(client_identifier: nil, client_name: nil)
|
10
|
+
@client_id = generate_nonce
|
11
|
+
user_id = `id -u`.chomp.to_i
|
12
|
+
@sock = UNIXSocket.new("/run/user/#{user_id}/org.keepassxc.KeePassXC.BrowserServer")
|
13
|
+
@private_key = RbNaCl::PrivateKey.generate
|
14
|
+
@client_identifier = client_identifier || to_b64(@private_key.public_key)
|
15
|
+
@client_name = client_name
|
16
|
+
end
|
17
|
+
|
18
|
+
def generate_nonce
|
19
|
+
to_b64 RbNaCl::Random.random_bytes
|
20
|
+
end
|
21
|
+
|
22
|
+
def change_public_keys
|
23
|
+
resp = send_msg(
|
24
|
+
action: 'change-public-keys',
|
25
|
+
publicKey: to_b64(@private_key.public_key),
|
26
|
+
nonce: generate_nonce,
|
27
|
+
clientID: @client_id
|
28
|
+
)
|
29
|
+
@session = RbNaCl::SimpleBox.from_keypair(resp['publicKey'].unpack1('m*'), @private_key)
|
30
|
+
|
31
|
+
resp
|
32
|
+
end
|
33
|
+
|
34
|
+
def associate
|
35
|
+
resp = send_encrypted_msg(
|
36
|
+
'action' => 'associate',
|
37
|
+
'key' => to_b64(@private_key.public_key),
|
38
|
+
'idKey' => @client_identifier
|
39
|
+
)
|
40
|
+
@client_name = resp['id']
|
41
|
+
|
42
|
+
resp
|
43
|
+
end
|
44
|
+
|
45
|
+
def test_associate
|
46
|
+
send_encrypted_msg(
|
47
|
+
'action' => 'test-associate',
|
48
|
+
'key' => @client_identifier,
|
49
|
+
'id' => @client_name
|
50
|
+
)
|
51
|
+
end
|
52
|
+
|
53
|
+
def get_logins(url)
|
54
|
+
send_encrypted_msg(
|
55
|
+
'action' => 'get-logins',
|
56
|
+
'url' => url,
|
57
|
+
'keys' => [
|
58
|
+
{
|
59
|
+
'id' => @client_name,
|
60
|
+
'key' => @client_identifier
|
61
|
+
}
|
62
|
+
]
|
63
|
+
)['entries']
|
64
|
+
end
|
65
|
+
|
66
|
+
def send_encrypted_msg(msg)
|
67
|
+
nonce, enc = encrypt(msg)
|
68
|
+
|
69
|
+
send_msg(
|
70
|
+
action: msg['action'],
|
71
|
+
message: to_b64(enc),
|
72
|
+
nonce: to_b64(nonce),
|
73
|
+
clientID: client_id
|
74
|
+
)
|
75
|
+
end
|
76
|
+
|
77
|
+
def encrypt(msg)
|
78
|
+
crypt = @session.box(JSON.dump(msg.transform_keys(&:to_s)))
|
79
|
+
nonce = crypt.slice!(0, RbNaCl::SecretBox.nonce_bytes)
|
80
|
+
|
81
|
+
[nonce, crypt]
|
82
|
+
end
|
83
|
+
|
84
|
+
def decrypt(msg, nonce:)
|
85
|
+
@session.decrypt(from_b64(nonce) + from_b64(msg))
|
86
|
+
end
|
87
|
+
|
88
|
+
def send_msg(msg)
|
89
|
+
@sock.send(JSON.dump(msg.transform_keys(&:to_s)), 0)
|
90
|
+
json = @sock.recvfrom(4096).first
|
91
|
+
resp = JSON.parse(json)
|
92
|
+
|
93
|
+
raise Error, resp['error'] if resp.key?('error')
|
94
|
+
resp = JSON.parse(decrypt(resp['message'], nonce: resp['nonce'])) if resp.key?('message')
|
95
|
+
binding.irb if resp['success'] != 'true'
|
96
|
+
|
97
|
+
resp
|
98
|
+
end
|
99
|
+
end
|
100
|
+
end
|
@@ -0,0 +1,50 @@
|
|
1
|
+
require 'fileutils'
|
2
|
+
require 'json'
|
3
|
+
|
4
|
+
module KeepassXC
|
5
|
+
class KeyStore
|
6
|
+
attr_reader :path
|
7
|
+
|
8
|
+
DEFAULT_PATH = File.join(Dir.home, '.config', 'keepassxc-rb')
|
9
|
+
def initialize(path: DEFAULT_PATH)
|
10
|
+
@path = path
|
11
|
+
end
|
12
|
+
|
13
|
+
def create
|
14
|
+
unless exist?
|
15
|
+
FileUtils.mkdir_p File.dirname(path)
|
16
|
+
File.write(path, JSON.dump(profiles: {}))
|
17
|
+
end
|
18
|
+
File.chmod(0600, path) unless secure?
|
19
|
+
end
|
20
|
+
|
21
|
+
def self.find_or_create(path: DEFAULT_PATH)
|
22
|
+
storage = new(path: path)
|
23
|
+
storage.create
|
24
|
+
storage
|
25
|
+
end
|
26
|
+
|
27
|
+
def raw
|
28
|
+
@raw ||= JSON.load_file(path)
|
29
|
+
rescue Errno::ENOENT
|
30
|
+
@raw = {}
|
31
|
+
end
|
32
|
+
|
33
|
+
def profiles
|
34
|
+
raw['profiles']
|
35
|
+
end
|
36
|
+
|
37
|
+
def save
|
38
|
+
create
|
39
|
+
File.write(path, JSON.dump(raw))
|
40
|
+
end
|
41
|
+
|
42
|
+
def secure?
|
43
|
+
File.stat(path).mode == 0600
|
44
|
+
end
|
45
|
+
|
46
|
+
def exist?
|
47
|
+
File.exist?(path)
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
metadata
ADDED
@@ -0,0 +1,54 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: keepassxc
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Holger Arndt
|
8
|
+
autorequire:
|
9
|
+
bindir: exe
|
10
|
+
cert_chain: []
|
11
|
+
date: 2021-04-16 00:00:00.000000000 Z
|
12
|
+
dependencies: []
|
13
|
+
description: Ruby bindings for the KeepassXC Browser API
|
14
|
+
email:
|
15
|
+
- keepassxc-ruby@kjarrigan.de
|
16
|
+
executables:
|
17
|
+
- keepassxc-rb
|
18
|
+
extensions: []
|
19
|
+
extra_rdoc_files: []
|
20
|
+
files:
|
21
|
+
- README.md
|
22
|
+
- exe/keepassxc-rb
|
23
|
+
- keepassxc.gemspec
|
24
|
+
- lib/keepassxc.rb
|
25
|
+
- lib/keepassxc/client.rb
|
26
|
+
- lib/keepassxc/helper.rb
|
27
|
+
- lib/keepassxc/key_store.rb
|
28
|
+
- lib/keepassxc/version.rb
|
29
|
+
homepage: https://github.com/Kjarrigan/keepassxc-ruby
|
30
|
+
licenses: []
|
31
|
+
metadata:
|
32
|
+
homepage_uri: https://github.com/Kjarrigan/keepassxc-ruby
|
33
|
+
source_code_uri: https://github.com/Kjarrigan/keepassxc-ruby
|
34
|
+
changelog_uri: https://github.com/Kjarrigan/keepassxc-ruby
|
35
|
+
post_install_message:
|
36
|
+
rdoc_options: []
|
37
|
+
require_paths:
|
38
|
+
- lib
|
39
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
40
|
+
requirements:
|
41
|
+
- - ">="
|
42
|
+
- !ruby/object:Gem::Version
|
43
|
+
version: 2.7.0
|
44
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
45
|
+
requirements:
|
46
|
+
- - ">="
|
47
|
+
- !ruby/object:Gem::Version
|
48
|
+
version: '0'
|
49
|
+
requirements: []
|
50
|
+
rubygems_version: 3.1.2
|
51
|
+
signing_key:
|
52
|
+
specification_version: 4
|
53
|
+
summary: Ruby bindings for the KeepassXC Browser API
|
54
|
+
test_files: []
|