feat: card-cryptmator plugin
This commit is contained in:
2
.gitignore
vendored
Normal file
2
.gitignore
vendored
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
.idea/
|
||||||
|
target/
|
||||||
22
LICENSE
Normal file
22
LICENSE
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
MIT License
|
||||||
|
|
||||||
|
Copyright (c) 2021-2024 Ralph Plawetzki
|
||||||
|
Copyright (c) 2024-2024 Hatter Jiang
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in all
|
||||||
|
copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
SOFTWARE.
|
||||||
58
README.md
58
README.md
@@ -1,2 +1,58 @@
|
|||||||
# card-cryptomator
|
# tinyencrypt-cryptomator
|
||||||
|
|
||||||
|
> This project is fork from https://github.com/purejava/keepassxc-cryptomator , add GnuPG support
|
||||||
|
|
||||||
|
[](https://github.com/jht5945/gnupg-cryptomator/releases)
|
||||||
|
[](https://github.com/jht5945/gnupg-cryptomator/blob/master/LICENSE)
|
||||||
|
|
||||||
|
Plug-in for Cryptomator to store vault passwords with card-cli encryption.
|
||||||
|
|
||||||
|
# Build Project
|
||||||
|
|
||||||
|
Requirement:
|
||||||
|
|
||||||
|
* JDK 17 or later
|
||||||
|
* Maven 3.8.4 or later
|
||||||
|
|
||||||
|
```shell
|
||||||
|
mvn package
|
||||||
|
```
|
||||||
|
|
||||||
|
Copy packaged plugin from `target/card-cryptomator-$VERSION.jar` to Cryptomator plugins directory.
|
||||||
|
> Usage reference [Wiki](https://github.com/purejava/keepassxc-cryptomator/wiki)
|
||||||
|
|
||||||
|
# Configuration
|
||||||
|
|
||||||
|
Configure file location:
|
||||||
|
|
||||||
|
* `/etc/cryptomator/card_config.json`
|
||||||
|
* `~/.config/cryptomator/card_config.json`
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
# Documentation
|
||||||
|
|
||||||
|
For documentation please take a look at the [Wiki](https://github.com/purejava/keepassxc-cryptomator/wiki).
|
||||||
|
|
||||||
|
Plugin location:
|
||||||
|
|
||||||
|
| OS | Default Dir |
|
||||||
|
| ---- | ---- |
|
||||||
|
| Mac | `~/Library/Application Support/Cryptomator/Plugins` |
|
||||||
|
| Linux | `~/.local/share/Cryptomator/plugins` |
|
||||||
|
| Windows | `%homepath%\AppData\Roaming\Cryptomator\Plugins` |
|
||||||
|
|
||||||
|
# How it works?
|
||||||
|
|
||||||
|
This plugin use card-cli encrypt and decrypt passwords.
|
||||||
|
|
||||||
|
# Copyright
|
||||||
|
|
||||||
|
Copyright (C) 2021-2024 Ralph Plawetzki<br>
|
||||||
|
Copyright (C) 2024-2024 Hatter Jiang
|
||||||
|
|
||||||
|
The Cryptomator logo is Copyright (C) of https://cryptomator.org/ <br>
|
||||||
|
The KeePassXC logo is Copyright (C) of https://keepassxc.org/
|
||||||
|
|||||||
7
build.json
Normal file
7
build.json
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
{
|
||||||
|
"java": "17",
|
||||||
|
"builder": {
|
||||||
|
"name": "maven",
|
||||||
|
"version": "3.8.4"
|
||||||
|
}
|
||||||
|
}
|
||||||
275
dependency-reduced-pom.xml
Normal file
275
dependency-reduced-pom.xml
Normal file
@@ -0,0 +1,275 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
|
||||||
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
<groupId>me.hatter</groupId>
|
||||||
|
<artifactId>card-cryptomator</artifactId>
|
||||||
|
<name>card-cryptomator</name>
|
||||||
|
<version>1.0.0</version>
|
||||||
|
<description>Plug-in for Cryptomator to store vault passwords with card-cli encryption.</description>
|
||||||
|
<url>https://git.hatter.ink/hatter/card-cryptomator</url>
|
||||||
|
<developers>
|
||||||
|
<developer>
|
||||||
|
<name>Ralph Plawetzki</name>
|
||||||
|
<email>ralph@purejava.org</email>
|
||||||
|
<organizationUrl>https://github.com/purejava</organizationUrl>
|
||||||
|
<timezone>+1</timezone>
|
||||||
|
</developer>
|
||||||
|
<developer>
|
||||||
|
<name>Hatter Jiang</name>
|
||||||
|
<email>jht5945@gmail.com</email>
|
||||||
|
<organizationUrl>https://github.com/jht5945</organizationUrl>
|
||||||
|
<timezone>+8</timezone>
|
||||||
|
</developer>
|
||||||
|
</developers>
|
||||||
|
<licenses>
|
||||||
|
<license>
|
||||||
|
<name>MIT License</name>
|
||||||
|
<url>https://opensource.org/licenses/MIT</url>
|
||||||
|
</license>
|
||||||
|
</licenses>
|
||||||
|
<scm>
|
||||||
|
<connection>scm:git:git@github.com:jht5945/tinyencrypt-cryptomator.git</connection>
|
||||||
|
<developerConnection>scm:git:git@github.com:jht5945/tinyencrypt-cryptomator.git</developerConnection>
|
||||||
|
<url>git@github.com:jht5945/tinyencrypt-cryptomator.git</url>
|
||||||
|
</scm>
|
||||||
|
<build>
|
||||||
|
<pluginManagement>
|
||||||
|
<plugins>
|
||||||
|
<plugin>
|
||||||
|
<artifactId>maven-clean-plugin</artifactId>
|
||||||
|
<version>3.3.2</version>
|
||||||
|
</plugin>
|
||||||
|
<plugin>
|
||||||
|
<artifactId>maven-resources-plugin</artifactId>
|
||||||
|
<version>3.3.1</version>
|
||||||
|
<configuration>
|
||||||
|
<includeEmptyDirs>false</includeEmptyDirs>
|
||||||
|
</configuration>
|
||||||
|
</plugin>
|
||||||
|
<plugin>
|
||||||
|
<artifactId>maven-compiler-plugin</artifactId>
|
||||||
|
<version>3.13.0</version>
|
||||||
|
</plugin>
|
||||||
|
<plugin>
|
||||||
|
<artifactId>maven-surefire-plugin</artifactId>
|
||||||
|
<version>3.3.0</version>
|
||||||
|
</plugin>
|
||||||
|
<plugin>
|
||||||
|
<artifactId>maven-jar-plugin</artifactId>
|
||||||
|
<version>3.4.1</version>
|
||||||
|
<configuration>
|
||||||
|
<skipIfEmpty>true</skipIfEmpty>
|
||||||
|
</configuration>
|
||||||
|
</plugin>
|
||||||
|
<plugin>
|
||||||
|
<artifactId>maven-install-plugin</artifactId>
|
||||||
|
<version>3.1.2</version>
|
||||||
|
</plugin>
|
||||||
|
<plugin>
|
||||||
|
<artifactId>maven-deploy-plugin</artifactId>
|
||||||
|
<version>3.1.2</version>
|
||||||
|
</plugin>
|
||||||
|
<plugin>
|
||||||
|
<artifactId>maven-site-plugin</artifactId>
|
||||||
|
<version>4.0.0-M15</version>
|
||||||
|
</plugin>
|
||||||
|
<plugin>
|
||||||
|
<artifactId>maven-project-info-reports-plugin</artifactId>
|
||||||
|
<version>3.6.0</version>
|
||||||
|
</plugin>
|
||||||
|
</plugins>
|
||||||
|
</pluginManagement>
|
||||||
|
<plugins>
|
||||||
|
<plugin>
|
||||||
|
<artifactId>maven-compiler-plugin</artifactId>
|
||||||
|
<version>3.13.0</version>
|
||||||
|
<configuration>
|
||||||
|
<source>17</source>
|
||||||
|
<target>17</target>
|
||||||
|
</configuration>
|
||||||
|
</plugin>
|
||||||
|
<plugin>
|
||||||
|
<artifactId>maven-source-plugin</artifactId>
|
||||||
|
<version>3.3.1</version>
|
||||||
|
<executions>
|
||||||
|
<execution>
|
||||||
|
<id>attach-sources</id>
|
||||||
|
<goals>
|
||||||
|
<goal>jar-no-fork</goal>
|
||||||
|
</goals>
|
||||||
|
</execution>
|
||||||
|
</executions>
|
||||||
|
</plugin>
|
||||||
|
<plugin>
|
||||||
|
<artifactId>maven-javadoc-plugin</artifactId>
|
||||||
|
<version>3.7.0</version>
|
||||||
|
<executions>
|
||||||
|
<execution>
|
||||||
|
<id>attach-javadocs</id>
|
||||||
|
<goals>
|
||||||
|
<goal>jar</goal>
|
||||||
|
</goals>
|
||||||
|
<configuration>
|
||||||
|
<failOnError>false</failOnError>
|
||||||
|
</configuration>
|
||||||
|
</execution>
|
||||||
|
</executions>
|
||||||
|
</plugin>
|
||||||
|
<plugin>
|
||||||
|
<artifactId>maven-shade-plugin</artifactId>
|
||||||
|
<version>3.6.0</version>
|
||||||
|
<executions>
|
||||||
|
<execution>
|
||||||
|
<phase>package</phase>
|
||||||
|
<goals>
|
||||||
|
<goal>shade</goal>
|
||||||
|
</goals>
|
||||||
|
</execution>
|
||||||
|
</executions>
|
||||||
|
</plugin>
|
||||||
|
<plugin>
|
||||||
|
<artifactId>maven-gpg-plugin</artifactId>
|
||||||
|
<version>3.2.4</version>
|
||||||
|
<executions>
|
||||||
|
<execution>
|
||||||
|
<id>sign-artifacts</id>
|
||||||
|
<phase>verify</phase>
|
||||||
|
<goals>
|
||||||
|
<goal>sign</goal>
|
||||||
|
</goals>
|
||||||
|
<configuration>
|
||||||
|
<gpgArguments>
|
||||||
|
<arg>--pinentry-mode</arg>
|
||||||
|
<arg>loopback</arg>
|
||||||
|
</gpgArguments>
|
||||||
|
</configuration>
|
||||||
|
</execution>
|
||||||
|
</executions>
|
||||||
|
</plugin>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.sonatype.plugins</groupId>
|
||||||
|
<artifactId>nexus-staging-maven-plugin</artifactId>
|
||||||
|
<version>1.7.0</version>
|
||||||
|
<extensions>true</extensions>
|
||||||
|
<configuration>
|
||||||
|
<serverId>ossrh</serverId>
|
||||||
|
<nexusUrl>https://oss.sonatype.org/</nexusUrl>
|
||||||
|
<autoReleaseAfterClose>false</autoReleaseAfterClose>
|
||||||
|
</configuration>
|
||||||
|
</plugin>
|
||||||
|
<plugin>
|
||||||
|
<artifactId>maven-surefire-plugin</artifactId>
|
||||||
|
<version>3.3.0</version>
|
||||||
|
<dependencies>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.junit.jupiter</groupId>
|
||||||
|
<artifactId>junit-jupiter-engine</artifactId>
|
||||||
|
<version>5.10.2</version>
|
||||||
|
</dependency>
|
||||||
|
</dependencies>
|
||||||
|
</plugin>
|
||||||
|
</plugins>
|
||||||
|
</build>
|
||||||
|
<profiles>
|
||||||
|
<profile>
|
||||||
|
<id>sign</id>
|
||||||
|
<build>
|
||||||
|
<plugins>
|
||||||
|
<plugin>
|
||||||
|
<artifactId>maven-gpg-plugin</artifactId>
|
||||||
|
<version>3.2.4</version>
|
||||||
|
<executions>
|
||||||
|
<execution>
|
||||||
|
<id>sign-artifacts</id>
|
||||||
|
<phase>verify</phase>
|
||||||
|
<goals>
|
||||||
|
<goal>sign</goal>
|
||||||
|
</goals>
|
||||||
|
<configuration>
|
||||||
|
<gpgArguments>
|
||||||
|
<arg>--pinentry-mode</arg>
|
||||||
|
<arg>loopback</arg>
|
||||||
|
</gpgArguments>
|
||||||
|
</configuration>
|
||||||
|
</execution>
|
||||||
|
</executions>
|
||||||
|
</plugin>
|
||||||
|
</plugins>
|
||||||
|
</build>
|
||||||
|
</profile>
|
||||||
|
</profiles>
|
||||||
|
<dependencies>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.slf4j</groupId>
|
||||||
|
<artifactId>slf4j-simple</artifactId>
|
||||||
|
<version>2.0.13</version>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.junit.jupiter</groupId>
|
||||||
|
<artifactId>junit-jupiter-api</artifactId>
|
||||||
|
<version>5.10.2</version>
|
||||||
|
<scope>test</scope>
|
||||||
|
<exclusions>
|
||||||
|
<exclusion>
|
||||||
|
<artifactId>opentest4j</artifactId>
|
||||||
|
<groupId>org.opentest4j</groupId>
|
||||||
|
</exclusion>
|
||||||
|
<exclusion>
|
||||||
|
<artifactId>junit-platform-commons</artifactId>
|
||||||
|
<groupId>org.junit.platform</groupId>
|
||||||
|
</exclusion>
|
||||||
|
<exclusion>
|
||||||
|
<artifactId>apiguardian-api</artifactId>
|
||||||
|
<groupId>org.apiguardian</groupId>
|
||||||
|
</exclusion>
|
||||||
|
</exclusions>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.junit.jupiter</groupId>
|
||||||
|
<artifactId>junit-jupiter-engine</artifactId>
|
||||||
|
<version>5.10.2</version>
|
||||||
|
<scope>test</scope>
|
||||||
|
<exclusions>
|
||||||
|
<exclusion>
|
||||||
|
<artifactId>junit-platform-engine</artifactId>
|
||||||
|
<groupId>org.junit.platform</groupId>
|
||||||
|
</exclusion>
|
||||||
|
<exclusion>
|
||||||
|
<artifactId>apiguardian-api</artifactId>
|
||||||
|
<groupId>org.apiguardian</groupId>
|
||||||
|
</exclusion>
|
||||||
|
</exclusions>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.junit.jupiter</groupId>
|
||||||
|
<artifactId>junit-jupiter</artifactId>
|
||||||
|
<version>5.10.2</version>
|
||||||
|
<scope>test</scope>
|
||||||
|
<exclusions>
|
||||||
|
<exclusion>
|
||||||
|
<artifactId>junit-jupiter-params</artifactId>
|
||||||
|
<groupId>org.junit.jupiter</groupId>
|
||||||
|
</exclusion>
|
||||||
|
</exclusions>
|
||||||
|
</dependency>
|
||||||
|
</dependencies>
|
||||||
|
<distributionManagement>
|
||||||
|
<repository>
|
||||||
|
<id>ossrh</id>
|
||||||
|
<url>https://oss.sonatype.org/service/local/staging/deploy/maven2/</url>
|
||||||
|
</repository>
|
||||||
|
<snapshotRepository>
|
||||||
|
<id>ossrh</id>
|
||||||
|
<url>https://oss.sonatype.org/content/repositories/snapshots</url>
|
||||||
|
</snapshotRepository>
|
||||||
|
</distributionManagement>
|
||||||
|
<properties>
|
||||||
|
<api.version>1.3.1</api.version>
|
||||||
|
<slf4j.version>2.0.13</slf4j.version>
|
||||||
|
<gson.version>2.11.0</gson.version>
|
||||||
|
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||||
|
<junit.version>5.10.2</junit.version>
|
||||||
|
<keepassxc-proxy.version>1.2.5</keepassxc-proxy.version>
|
||||||
|
</properties>
|
||||||
|
</project>
|
||||||
BIN
keepassxc-cryptomator.png
Normal file
BIN
keepassxc-cryptomator.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 22 KiB |
258
keepassxc-cryptomator.svg
Normal file
258
keepassxc-cryptomator.svg
Normal file
@@ -0,0 +1,258 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||||
|
<svg
|
||||||
|
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||||
|
xmlns:cc="http://creativecommons.org/ns#"
|
||||||
|
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||||
|
xmlns:svg="http://www.w3.org/2000/svg"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||||
|
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||||
|
width="47.142086mm"
|
||||||
|
height="51.849831mm"
|
||||||
|
viewBox="0 0 47.142086 51.849831"
|
||||||
|
version="1.1"
|
||||||
|
id="svg952"
|
||||||
|
inkscape:version="1.0.1 (3bc2e813f5, 2020-09-07, custom)"
|
||||||
|
sodipodi:docname="Zeichnung.svg">
|
||||||
|
<defs
|
||||||
|
id="defs946">
|
||||||
|
<linearGradient
|
||||||
|
id="SVGID_1_"
|
||||||
|
gradientUnits="userSpaceOnUse"
|
||||||
|
x1="50"
|
||||||
|
y1="-654.86328"
|
||||||
|
x2="50"
|
||||||
|
y2="-728.46722"
|
||||||
|
gradientTransform="matrix(0.09165435,-0.05291667,-0.05291667,-0.09165435,73.377481,82.400217)">
|
||||||
|
<stop
|
||||||
|
offset="0"
|
||||||
|
style="stop-color:#35762e"
|
||||||
|
id="stop4" />
|
||||||
|
<stop
|
||||||
|
offset="1"
|
||||||
|
style="stop-color:#6daa43"
|
||||||
|
id="stop6" />
|
||||||
|
</linearGradient>
|
||||||
|
</defs>
|
||||||
|
<sodipodi:namedview
|
||||||
|
id="base"
|
||||||
|
pagecolor="#ffffff"
|
||||||
|
bordercolor="#666666"
|
||||||
|
borderopacity="1.0"
|
||||||
|
inkscape:pageopacity="0.0"
|
||||||
|
inkscape:pageshadow="2"
|
||||||
|
inkscape:zoom="2.6415902"
|
||||||
|
inkscape:cx="89.087397"
|
||||||
|
inkscape:cy="97.983946"
|
||||||
|
inkscape:document-units="mm"
|
||||||
|
inkscape:current-layer="layer1"
|
||||||
|
inkscape:document-rotation="0"
|
||||||
|
showgrid="false"
|
||||||
|
inkscape:window-width="1440"
|
||||||
|
inkscape:window-height="836"
|
||||||
|
inkscape:window-x="0"
|
||||||
|
inkscape:window-y="27"
|
||||||
|
inkscape:window-maximized="1" />
|
||||||
|
<metadata
|
||||||
|
id="metadata949">
|
||||||
|
<rdf:RDF>
|
||||||
|
<cc:Work
|
||||||
|
rdf:about="">
|
||||||
|
<dc:format>image/svg+xml</dc:format>
|
||||||
|
<dc:type
|
||||||
|
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||||
|
<dc:title />
|
||||||
|
</cc:Work>
|
||||||
|
</rdf:RDF>
|
||||||
|
</metadata>
|
||||||
|
<g
|
||||||
|
inkscape:label="Ebene 1"
|
||||||
|
inkscape:groupmode="layer"
|
||||||
|
id="layer1"
|
||||||
|
transform="translate(-82.262292,-122.24175)">
|
||||||
|
<g
|
||||||
|
id="g6"
|
||||||
|
style="fill:#666666;stroke:#008000;stroke-opacity:1"
|
||||||
|
transform="matrix(-0.13229167,-0.22913589,0.22913589,-0.13229167,107.97964,157.68609)">
|
||||||
|
<path
|
||||||
|
class="st0"
|
||||||
|
d="m 44.95,24.54 c -8.971761,0.03124 0.868039,0 24.39,0 v 27.11 c 0,14.91 -12.2,27.11 -27.1,27.11 1.08,10.77 3.62,18.33 7.1,23.06 2.18,2.96 4.69,4.66 7.35,5.21 2.86,0.59 6.17,-0.01 9.72,-1.68 6.76,-3.19 13.88,-9.95 20.23,-19.71 2.35,-3.62 7.19,-4.64 10.8,-2.29 3.62,2.35 4.64,7.19 2.3,10.8 -7.98,12.26 -17.37,20.97 -26.65,25.34 -6.6,3.11 -13.24,4.13 -19.51,2.84 C 47.12,121 41.35,117.32 36.74,111.06 31.49,103.92 27.79,93.27 26.52,78.75 11.88,78.44 0,66.37 0,51.65 V 24.54 h 11.27 c 7.299826,-0.04034 -0.01719,0 33.68,0 z"
|
||||||
|
id="path4"
|
||||||
|
style="fill:#666666;stroke:#008000;stroke-opacity:1"
|
||||||
|
sodipodi:nodetypes="ccscccccccccccsccc" />
|
||||||
|
</g>
|
||||||
|
<circle
|
||||||
|
style="clip-rule:evenodd;fill:#ffffff;fill-rule:evenodd;stroke:#515151;stroke-width:0.331459;stroke-linecap:round;stroke-linejoin:round"
|
||||||
|
cx="27.638317"
|
||||||
|
cy="181.29776"
|
||||||
|
r="4.8577499"
|
||||||
|
id="circle2"
|
||||||
|
transform="rotate(-30)" />
|
||||||
|
<path
|
||||||
|
style="fill:url(#SVGID_1_);stroke-width:0.105833"
|
||||||
|
d="m 113.27757,139.50771 c 0.0356,0.0405 0.0713,0.0811 0.0977,0.12689 0.20109,0.34829 0.081,0.79646 -0.26729,0.99754 -0.34828,0.20109 -0.79645,0.081 -0.99754,-0.26729 -0.0265,-0.0458 -0.0438,-0.0969 -0.061,-0.14806 0.18047,-0.15308 0.3807,-0.29312 0.58233,-0.40954 0.20552,-0.13087 0.42303,-0.21979 0.64584,-0.29954 z m -1.94768,2.15102 c 0.40746,0.70574 1.17445,1.0817 1.94341,1.01657 l 1.85737,3.21707 1.19994,0.32152 0.32152,-1.19993 -0.43211,-0.64262 0.15107,-0.56383 -0.56382,-0.15108 0.22855,-0.85297 -0.85297,-0.22855 -0.38809,-0.77802 c 0.43171,-0.62809 0.49878,-1.48559 0.0913,-2.19133 -0.0688,-0.11915 -0.14146,-0.22384 -0.23775,-0.32712 1.37191,0.0267 2.63016,0.76673 3.32724,1.95294 1.0795,1.86975 0.44562,4.26434 -1.43329,5.34913 -1.86975,1.0795 -4.26434,0.44562 -5.34913,-1.43329 -0.68792,-1.19151 -0.69967,-2.65119 -0.0277,-3.85795 0.0505,0.12974 0.0956,0.25031 0.16442,0.36946 z m 2.44346,1.29002 0.25663,-0.14817 1.46579,2.53883 -0.25663,0.14816 z"
|
||||||
|
id="path9" />
|
||||||
|
<g
|
||||||
|
id="g6-3"
|
||||||
|
style="fill:#666666;stroke:#008000;stroke-opacity:1"
|
||||||
|
transform="matrix(0.13229167,0.22913589,-0.22913589,0.13229167,103.68703,138.64724)">
|
||||||
|
<path
|
||||||
|
class="st0"
|
||||||
|
d="m 14.7,0 h 6.28 c 1.88,0 3.42,1.54 3.42,3.42 V 24.54 H 44.95 V 3.42 C 44.95,1.54 46.49,0 48.37,0 h 6.28 c 1.88,0 3.42,1.54 3.42,3.42 v 21.12 h 11.27 v 27.11 c 0,14.91 -12.2,27.11 -27.1,27.11 1.08,10.77 3.62,18.33 7.1,23.06 2.18,2.96 4.69,4.66 7.35,5.21 2.86,0.59 6.17,-0.01 9.72,-1.68 6.76,-3.19 13.88,-9.95 20.23,-19.71 2.35,-3.62 7.19,-4.64 10.8,-2.29 3.62,2.35 4.64,7.19 2.3,10.8 -7.98,12.26 -17.37,20.97 -26.65,25.34 -6.6,3.11 -13.24,4.13 -19.51,2.84 C 47.12,121 41.35,117.32 36.74,111.06 31.49,103.92 27.79,93.27 26.52,78.75 11.88,78.44 0,66.37 0,51.65 V 24.54 H 11.27 V 3.42 C 11.27,1.54 12.81,0 14.7,0 Z"
|
||||||
|
id="path4-6"
|
||||||
|
style="fill:#666666;stroke:#008000;stroke-opacity:1" />
|
||||||
|
</g>
|
||||||
|
<path
|
||||||
|
d="m 94.582125,149.19927 c -1.448673,0.83639 -1.538826,2.52713 -0.846069,3.72701 l 4.496797,-2.59622 c -0.692756,-1.19989 -2.304688,-1.90793 -3.650728,-1.13079 z"
|
||||||
|
fill="#cfcfcf"
|
||||||
|
id="path2"
|
||||||
|
style="stroke-width:0.0098923" />
|
||||||
|
<path
|
||||||
|
d="m 94.84526,149.65503 c -1.176843,0.67945 -1.250139,2.05296 -0.687367,3.02771 l 1.946159,-0.84742 1.706964,-1.26171 c -0.562772,-0.97475 -1.872268,-1.54991 -2.965756,-0.91858 z"
|
||||||
|
fill="#585e62"
|
||||||
|
id="path4-5"
|
||||||
|
style="stroke-width:0.0098923" />
|
||||||
|
<path
|
||||||
|
d="m 94.274333,157.82422 a 0.19784549,0.19784549 0 0 1 -0.216358,-0.33062 0.42338937,0.42338937 0 1 0 -0.469621,0.0219 0.19784549,0.19784549 0 0 1 -0.204335,0.33855 0.81898146,0.81898146 0 1 1 0.909459,-0.0424 0.21545374,0.21545374 0 0 1 -0.01914,0.0125 z"
|
||||||
|
fill="#585e62"
|
||||||
|
id="path6"
|
||||||
|
style="stroke-width:0.0098923" />
|
||||||
|
<rect
|
||||||
|
fill="#cfcfcf"
|
||||||
|
height="1.426367"
|
||||||
|
rx="0.48887613"
|
||||||
|
transform="rotate(-2.91)"
|
||||||
|
width="1.0355232"
|
||||||
|
x="85.189171"
|
||||||
|
y="159.69926"
|
||||||
|
id="rect8"
|
||||||
|
style="stroke-width:0.0098923" />
|
||||||
|
<path
|
||||||
|
d="m 93.350895,154.4092 0.620433,-0.0315 0.04748,0.93411 a 0.31061742,0.31061742 0 0 1 -0.294448,0.32598 0.31061742,0.31061742 0 0 1 -0.325985,-0.29445 z"
|
||||||
|
fill="#585e62"
|
||||||
|
id="path10"
|
||||||
|
style="stroke-width:0.0098923" />
|
||||||
|
<circle
|
||||||
|
cx="4.0454521"
|
||||||
|
cy="180.33498"
|
||||||
|
fill="#cfcfcf"
|
||||||
|
r="0.74241537"
|
||||||
|
id="circle12"
|
||||||
|
style="stroke-width:0.0098923"
|
||||||
|
transform="rotate(-30)" />
|
||||||
|
<path
|
||||||
|
d="m 93.649966,153.41325 a 0.74281091,0.74281091 0 0 0 -0.709153,0.57665 0.74251415,0.74251415 0 0 1 1.065394,0.82483 0.74251415,0.74251415 0 0 0 -0.356241,-1.40148 z"
|
||||||
|
fill="#b1b1b1"
|
||||||
|
id="path14"
|
||||||
|
style="stroke-width:0.0098923" />
|
||||||
|
<path
|
||||||
|
d="m 102.22884,153.23168 a 0.21852035,0.21852035 0 0 1 -0.0202,0.0102 0.81908036,0.81908036 0 1 1 0.4915,-0.76648 0.19784549,0.19784549 0 1 1 -0.39536,0.008 0.42338937,0.42338937 0 1 0 -0.25385,0.39581 0.19784549,0.19784549 0 0 1 0.17814,0.35268 z"
|
||||||
|
fill="#585e62"
|
||||||
|
id="path16"
|
||||||
|
style="stroke-width:0.0098923" />
|
||||||
|
<rect
|
||||||
|
fill="#cfcfcf"
|
||||||
|
height="1.426367"
|
||||||
|
rx="0.48887613"
|
||||||
|
transform="rotate(122.91)"
|
||||||
|
width="1.0355232"
|
||||||
|
x="72.147804"
|
||||||
|
y="-167.79698"
|
||||||
|
id="rect18"
|
||||||
|
style="stroke-width:0.0098923" />
|
||||||
|
<path
|
||||||
|
d="m 100.61039,151.66275 a 0.31061742,0.31061742 0 0 1 -0.42954,0.092 l -0.785222,-0.50818 0.337532,-0.52154 0.78522,0.50817 a 0.31061742,0.31061742 0 0 1 0.092,0.42954 z"
|
||||||
|
fill="#585e62"
|
||||||
|
id="path20"
|
||||||
|
style="stroke-width:0.0098923" />
|
||||||
|
<circle
|
||||||
|
cx="10.603434"
|
||||||
|
cy="180.33498"
|
||||||
|
fill="#cfcfcf"
|
||||||
|
r="0.74241537"
|
||||||
|
id="circle22"
|
||||||
|
style="stroke-width:0.0098923"
|
||||||
|
transform="rotate(-30)" />
|
||||||
|
<path
|
||||||
|
d="m 98.720836,150.48558 a 0.74271198,0.74271198 0 0 1 0.853889,-0.32577 0.74251415,0.74251415 0 0 0 0.181968,1.33488 0.74241522,0.74241522 0 0 1 -1.035857,-1.00911 z"
|
||||||
|
fill="#b1b1b1"
|
||||||
|
id="path24"
|
||||||
|
style="stroke-width:0.0098923" />
|
||||||
|
<path
|
||||||
|
d="m 96.628898,158.7571 c -0.31415,0.18138 -0.771089,-0.01 -1.1373,-0.47593 -0.196501,-0.25013 -0.341801,-0.5473 -0.409423,-0.83734 -0.07272,-0.31212 -0.04652,-0.58528 0.07309,-0.77005 a 0.51162844,0.51162844 0 0 1 0.174066,-0.1672 l 0.886851,-0.51203 1.2994,2.25063 z"
|
||||||
|
fill="#585e62"
|
||||||
|
id="path26"
|
||||||
|
style="stroke-width:0.0098923" />
|
||||||
|
<path
|
||||||
|
d="m 97.508296,158.24938 c -0.182132,0.10516 -0.529929,-0.14924 -0.86547,-0.63287 -0.180051,-0.25963 -0.333661,-0.552 -0.432725,-0.82389 -0.10664,-0.29253 -0.138444,-0.53221 -0.09011,-0.67582 0.01848,-0.0549 0.04822,-0.0945 0.08874,-0.11795 0.04052,-0.0234 0.08991,-0.0291 0.146482,-0.0183 l 0.642568,0.12967 c 0.224583,0.0453 0.516933,0.4326 0.677816,0.77377 0.124006,0.26286 0.172421,0.49649 0.130133,0.62485 l -0.208944,0.62118 c -0.0182,0.0562 -0.0482,0.0961 -0.08848,0.11938 z"
|
||||||
|
fill="#585e62"
|
||||||
|
id="path28"
|
||||||
|
style="stroke-width:0.0098923" />
|
||||||
|
<path
|
||||||
|
d="m 96.393592,156.13782 0.64194,0.12957 c 0.144747,0.0295 0.387014,0.31857 0.541652,0.64575 0.102905,0.21782 0.14041,0.39812 0.111521,0.48539 l -0.20875,0.62072 c -0.07816,0.23223 -0.419847,0.0205 -0.76296,-0.47411 -0.34311,-0.49457 -0.557467,-1.08427 -0.479459,-1.31675 0.02589,-0.0768 0.08216,-0.10501 0.156063,-0.0906 z"
|
||||||
|
fill="#35393b"
|
||||||
|
id="path30"
|
||||||
|
style="stroke-width:0.0098923" />
|
||||||
|
<path
|
||||||
|
d="m 101.78578,155.77977 c 0.31407,-0.18132 0.37688,-0.67278 0.15648,-1.22289 -0.11837,-0.29524 -0.30307,-0.56966 -0.52045,-0.77324 -0.23394,-0.21904 -0.48361,-0.33293 -0.70342,-0.32173 a 0.51162844,0.51162844 0 0 0 -0.23184,0.0671 l -0.886934,0.51207 1.299404,2.25063 z"
|
||||||
|
fill="#585e62"
|
||||||
|
id="path32"
|
||||||
|
style="stroke-width:0.0098923" />
|
||||||
|
<path
|
||||||
|
d="m 100.90638,156.2875 c 0.18214,-0.10516 0.13573,-0.53355 -0.11535,-1.06596 -0.13482,-0.28574 -0.31122,-0.56496 -0.49714,-0.7867 -0.20002,-0.23861 -0.391772,-0.38595 -0.540226,-0.41595 -0.05683,-0.0114 -0.105989,-0.006 -0.146509,0.0179 -0.04052,0.0234 -0.07012,0.0633 -0.08919,0.11775 l -0.208916,0.62126 c -0.07312,0.21721 0.11617,0.66398 0.331195,0.97389 0.165644,0.23882 0.34376,0.39757 0.476066,0.42512 l 0.64235,0.12968 c 0.0579,0.0122 0.10745,0.006 0.14771,-0.017 z"
|
||||||
|
fill="#585e62"
|
||||||
|
id="path34"
|
||||||
|
style="stroke-width:0.0098923" />
|
||||||
|
<path
|
||||||
|
d="m 99.63507,154.26636 -0.20875,0.62072 c -0.04709,0.13982 0.08201,0.4942 0.2883,0.79157 0.137183,0.19802 0.274569,0.32065 0.36459,0.33927 l 0.64194,0.12957 c 0.2406,0.0485 0.22756,-0.35332 -0.0292,-0.89775 -0.25675,-0.54443 -0.66027,-1.02492 -0.900608,-1.0736 -0.07955,-0.0155 -0.131817,0.019 -0.156261,0.0902 z"
|
||||||
|
fill="#35393b"
|
||||||
|
id="path36"
|
||||||
|
style="stroke-width:0.0098923" />
|
||||||
|
<path
|
||||||
|
d="m 99.35002,151.60246 a 0.82719201,0.82719201 0 0 1 -0.230348,-0.38788 c -0.13651,-0.52807 -0.50953,-0.98264 -0.50953,-0.98264 -1.871225,0.42046 -2.573575,1.48037 -2.573575,1.48037 0,0 -1.268496,0.074 -2.572313,1.47999 0,0 0.205571,0.55114 0.593562,0.9347 a 0.8278845,0.8278845 0 0 1 0.219583,0.39398 c 0.04287,0.17594 0.128265,0.43425 0.29749,0.72834 1.228419,2.13501 4.234325,1.28 4.234325,1.28 0,0 2.249816,-2.16876 1.021344,-4.30385 -0.169651,-0.29385 -0.349786,-0.49723 -0.480542,-0.623 z"
|
||||||
|
fill="#cfcfcf"
|
||||||
|
id="path38"
|
||||||
|
style="stroke-width:0.0098923" />
|
||||||
|
<path
|
||||||
|
d="m 98.579909,156.13055 c -0.513012,0.11492 -2.703201,0.49554 -3.622069,-1.10153 -0.146654,-0.25401 -0.217385,-0.47326 -0.250876,-0.61259 a 1.2691788,1.2691788 0 0 0 -0.338435,-0.60418 c -0.164799,-0.16278 -0.292223,-0.36964 -0.375791,-0.52882 0.296192,-0.28787 0.611048,-0.52836 0.938639,-0.71692 0.648772,-0.3732 1.130704,-0.41294 1.135315,-0.41366 l 0.22528,-0.0132 0.113783,-0.18357 c 9.26e-4,-5.3e-4 0.277398,-0.39718 0.925947,-0.77036 0.327635,-0.18849 0.693764,-0.33978 1.091629,-0.45115 0.09546,0.15209 0.210333,0.36643 0.268261,0.59068 a 1.2694755,1.2694755 0 0 0 0.35215,0.59626 c 0.103069,0.0994 0.257036,0.2707 0.403308,0.52504 0.92282,1.60393 -0.508578,3.29881 -0.86713,3.68401 z"
|
||||||
|
fill="#49b04a"
|
||||||
|
id="path40"
|
||||||
|
style="stroke-width:0.0098923" />
|
||||||
|
<path
|
||||||
|
d="m 97.442395,153.01658 a 0.56841012,0.56841012 0 1 0 -0.324383,0.82604 l 0.393427,1.32027 0.446243,-0.11086 0.320164,-0.33002 -0.943321,-1.00394 a 0.56841012,0.56841012 0 0 0 0.107871,-0.70149 z"
|
||||||
|
fill="#35393b"
|
||||||
|
id="path42"
|
||||||
|
style="stroke-width:0.0098923" />
|
||||||
|
<g
|
||||||
|
fill="#49b04a"
|
||||||
|
id="g56"
|
||||||
|
transform="matrix(0.00856696,-0.00494614,0.00494614,0.00856696,89.847252,151.93294)">
|
||||||
|
<path
|
||||||
|
d="M 454.94,131.08 A 60.64,60.64 0 0 0 394.3,191.72 H 515.58 A 60.64,60.64 0 0 0 454.94,131.08 Z"
|
||||||
|
id="path44" />
|
||||||
|
<path
|
||||||
|
d="m 642.38,131.08 a 60.64,60.64 0 0 0 -60.64,60.64 H 703 a 60.64,60.64 0 0 0 -60.62,-60.64 z"
|
||||||
|
id="path46" />
|
||||||
|
<circle
|
||||||
|
cx="483.23001"
|
||||||
|
cy="229.42999"
|
||||||
|
r="11.52"
|
||||||
|
id="circle48" />
|
||||||
|
<circle
|
||||||
|
cx="528.52002"
|
||||||
|
cy="229.42999"
|
||||||
|
r="11.52"
|
||||||
|
id="circle50" />
|
||||||
|
<circle
|
||||||
|
cx="573.79999"
|
||||||
|
cy="229.42999"
|
||||||
|
r="11.52"
|
||||||
|
id="circle52" />
|
||||||
|
<circle
|
||||||
|
cx="619.09003"
|
||||||
|
cy="229.42999"
|
||||||
|
r="11.52"
|
||||||
|
id="circle54" />
|
||||||
|
</g>
|
||||||
|
</g>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 13 KiB |
286
pom.xml
Normal file
286
pom.xml
Normal file
@@ -0,0 +1,286 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||||
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||||
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
<groupId>me.hatter</groupId>
|
||||||
|
<artifactId>card-cryptomator</artifactId>
|
||||||
|
<version>1.0.0</version>
|
||||||
|
|
||||||
|
<name>card-cryptomator</name>
|
||||||
|
<description>Plug-in for Cryptomator to store vault passwords with card-cli encryption.</description>
|
||||||
|
<url>https://git.hatter.ink/hatter/card-cryptomator</url>
|
||||||
|
|
||||||
|
<licenses>
|
||||||
|
<license>
|
||||||
|
<name>MIT License</name>
|
||||||
|
<url>https://opensource.org/licenses/MIT</url>
|
||||||
|
</license>
|
||||||
|
</licenses>
|
||||||
|
|
||||||
|
<developers>
|
||||||
|
<developer>
|
||||||
|
<name>Ralph Plawetzki</name>
|
||||||
|
<email>ralph@purejava.org</email>
|
||||||
|
<timezone>+1</timezone>
|
||||||
|
<organization/>
|
||||||
|
<organizationUrl>https://github.com/purejava</organizationUrl>
|
||||||
|
</developer>
|
||||||
|
<developer>
|
||||||
|
<name>Hatter Jiang</name>
|
||||||
|
<email>jht5945@gmail.com</email>
|
||||||
|
<timezone>+8</timezone>
|
||||||
|
<organization/>
|
||||||
|
<organizationUrl>https://github.com/jht5945</organizationUrl>
|
||||||
|
</developer>
|
||||||
|
</developers>
|
||||||
|
|
||||||
|
<scm>
|
||||||
|
<connection>scm:git:git@github.com:jht5945/tinyencrypt-cryptomator.git</connection>
|
||||||
|
<developerConnection>scm:git:git@github.com:jht5945/tinyencrypt-cryptomator.git</developerConnection>
|
||||||
|
<url>git@github.com:jht5945/tinyencrypt-cryptomator.git</url>
|
||||||
|
</scm>
|
||||||
|
|
||||||
|
<distributionManagement>
|
||||||
|
<snapshotRepository>
|
||||||
|
<id>ossrh</id>
|
||||||
|
<url>https://oss.sonatype.org/content/repositories/snapshots</url>
|
||||||
|
</snapshotRepository>
|
||||||
|
<repository>
|
||||||
|
<id>ossrh</id>
|
||||||
|
<url>https://oss.sonatype.org/service/local/staging/deploy/maven2/</url>
|
||||||
|
</repository>
|
||||||
|
</distributionManagement>
|
||||||
|
|
||||||
|
<properties>
|
||||||
|
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||||
|
|
||||||
|
<!-- runtime dependencies -->
|
||||||
|
<api.version>1.3.1</api.version>
|
||||||
|
<keepassxc-proxy.version>1.2.5</keepassxc-proxy.version>
|
||||||
|
<gson.version>2.11.0</gson.version>
|
||||||
|
<slf4j.version>2.0.13</slf4j.version>
|
||||||
|
<junit.version>5.10.2</junit.version>
|
||||||
|
</properties>
|
||||||
|
|
||||||
|
<dependencies>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.cryptomator</groupId>
|
||||||
|
<artifactId>integrations-api</artifactId>
|
||||||
|
<version>${api.version}</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.slf4j</groupId>
|
||||||
|
<artifactId>slf4j-api</artifactId>
|
||||||
|
<version>${slf4j.version}</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.slf4j</groupId>
|
||||||
|
<artifactId>slf4j-simple</artifactId>
|
||||||
|
<version>${slf4j.version}</version>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.google.code.gson</groupId>
|
||||||
|
<artifactId>gson</artifactId>
|
||||||
|
<version>${gson.version}</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.purejava</groupId>
|
||||||
|
<artifactId>keepassxc-proxy-access</artifactId>
|
||||||
|
<version>${keepassxc-proxy.version}</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.junit.jupiter</groupId>
|
||||||
|
<artifactId>junit-jupiter-api</artifactId>
|
||||||
|
<version>${junit.version}</version>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.junit.jupiter</groupId>
|
||||||
|
<artifactId>junit-jupiter-engine</artifactId>
|
||||||
|
<version>${junit.version}</version>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.junit.jupiter</groupId>
|
||||||
|
<artifactId>junit-jupiter</artifactId>
|
||||||
|
<version>${junit.version}</version>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
|
</dependencies>
|
||||||
|
|
||||||
|
<build>
|
||||||
|
<pluginManagement>
|
||||||
|
<plugins>
|
||||||
|
<plugin>
|
||||||
|
<artifactId>maven-clean-plugin</artifactId>
|
||||||
|
<version>3.3.2</version>
|
||||||
|
</plugin>
|
||||||
|
<plugin>
|
||||||
|
<artifactId>maven-resources-plugin</artifactId>
|
||||||
|
<version>3.3.1</version>
|
||||||
|
<configuration>
|
||||||
|
<includeEmptyDirs>false</includeEmptyDirs>
|
||||||
|
</configuration>
|
||||||
|
</plugin>
|
||||||
|
<plugin>
|
||||||
|
<artifactId>maven-compiler-plugin</artifactId>
|
||||||
|
<version>3.13.0</version>
|
||||||
|
</plugin>
|
||||||
|
<plugin>
|
||||||
|
<artifactId>maven-surefire-plugin</artifactId>
|
||||||
|
<version>3.3.0</version>
|
||||||
|
</plugin>
|
||||||
|
<plugin>
|
||||||
|
<artifactId>maven-jar-plugin</artifactId>
|
||||||
|
<version>3.4.1</version>
|
||||||
|
<configuration>
|
||||||
|
<skipIfEmpty>true</skipIfEmpty>
|
||||||
|
</configuration>
|
||||||
|
</plugin>
|
||||||
|
<plugin>
|
||||||
|
<artifactId>maven-install-plugin</artifactId>
|
||||||
|
<version>3.1.2</version>
|
||||||
|
</plugin>
|
||||||
|
<plugin>
|
||||||
|
<artifactId>maven-deploy-plugin</artifactId>
|
||||||
|
<version>3.1.2</version>
|
||||||
|
</plugin>
|
||||||
|
<plugin>
|
||||||
|
<artifactId>maven-site-plugin</artifactId>
|
||||||
|
<version>4.0.0-M15</version>
|
||||||
|
</plugin>
|
||||||
|
<plugin>
|
||||||
|
<artifactId>maven-project-info-reports-plugin</artifactId>
|
||||||
|
<version>3.6.0</version>
|
||||||
|
</plugin>
|
||||||
|
</plugins>
|
||||||
|
</pluginManagement>
|
||||||
|
|
||||||
|
<plugins>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
<artifactId>maven-compiler-plugin</artifactId>
|
||||||
|
<version>3.13.0</version>
|
||||||
|
<configuration>
|
||||||
|
<source>17</source>
|
||||||
|
<target>17</target>
|
||||||
|
</configuration>
|
||||||
|
</plugin>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
<artifactId>maven-source-plugin</artifactId>
|
||||||
|
<version>3.3.1</version>
|
||||||
|
<executions>
|
||||||
|
<execution>
|
||||||
|
<id>attach-sources</id>
|
||||||
|
<goals>
|
||||||
|
<goal>jar-no-fork</goal>
|
||||||
|
</goals>
|
||||||
|
</execution>
|
||||||
|
</executions>
|
||||||
|
</plugin>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
<artifactId>maven-javadoc-plugin</artifactId>
|
||||||
|
<version>3.7.0</version>
|
||||||
|
<executions>
|
||||||
|
<execution>
|
||||||
|
<id>attach-javadocs</id>
|
||||||
|
<goals>
|
||||||
|
<goal>jar</goal>
|
||||||
|
</goals>
|
||||||
|
<configuration>
|
||||||
|
<failOnError>false</failOnError>
|
||||||
|
</configuration>
|
||||||
|
</execution>
|
||||||
|
</executions>
|
||||||
|
</plugin>
|
||||||
|
<plugin>
|
||||||
|
<artifactId>maven-shade-plugin</artifactId>
|
||||||
|
<version>3.6.0</version>
|
||||||
|
<executions>
|
||||||
|
<execution>
|
||||||
|
<phase>package</phase>
|
||||||
|
<goals>
|
||||||
|
<goal>shade</goal>
|
||||||
|
</goals>
|
||||||
|
</execution>
|
||||||
|
</executions>
|
||||||
|
</plugin>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
<artifactId>maven-gpg-plugin</artifactId>
|
||||||
|
<version>3.2.4</version>
|
||||||
|
<executions>
|
||||||
|
<execution>
|
||||||
|
<id>sign-artifacts</id>
|
||||||
|
<phase>verify</phase>
|
||||||
|
<goals>
|
||||||
|
<goal>sign</goal>
|
||||||
|
</goals>
|
||||||
|
<configuration>
|
||||||
|
<gpgArguments>
|
||||||
|
<arg>--pinentry-mode</arg>
|
||||||
|
<arg>loopback</arg>
|
||||||
|
</gpgArguments>
|
||||||
|
</configuration>
|
||||||
|
</execution>
|
||||||
|
</executions>
|
||||||
|
</plugin>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.sonatype.plugins</groupId>
|
||||||
|
<artifactId>nexus-staging-maven-plugin</artifactId>
|
||||||
|
<version>1.7.0</version>
|
||||||
|
<extensions>true</extensions>
|
||||||
|
<configuration>
|
||||||
|
<serverId>ossrh</serverId>
|
||||||
|
<nexusUrl>https://oss.sonatype.org/</nexusUrl>
|
||||||
|
<autoReleaseAfterClose>false</autoReleaseAfterClose>
|
||||||
|
</configuration>
|
||||||
|
</plugin>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
<artifactId>maven-surefire-plugin</artifactId>
|
||||||
|
<version>3.3.0</version>
|
||||||
|
<dependencies>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.junit.jupiter</groupId>
|
||||||
|
<artifactId>junit-jupiter-engine</artifactId>
|
||||||
|
<version>5.10.2</version>
|
||||||
|
</dependency>
|
||||||
|
</dependencies>
|
||||||
|
</plugin>
|
||||||
|
</plugins>
|
||||||
|
</build>
|
||||||
|
<profiles>
|
||||||
|
<profile>
|
||||||
|
<id>sign</id>
|
||||||
|
<build>
|
||||||
|
<plugins>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
<artifactId>maven-gpg-plugin</artifactId>
|
||||||
|
<version>3.2.4</version>
|
||||||
|
<executions>
|
||||||
|
<execution>
|
||||||
|
<id>sign-artifacts</id>
|
||||||
|
<phase>verify</phase>
|
||||||
|
<goals>
|
||||||
|
<goal>sign</goal>
|
||||||
|
</goals>
|
||||||
|
<configuration>
|
||||||
|
<gpgArguments>
|
||||||
|
<arg>--pinentry-mode</arg>
|
||||||
|
<arg>loopback</arg>
|
||||||
|
</gpgArguments>
|
||||||
|
</configuration>
|
||||||
|
</execution>
|
||||||
|
</executions>
|
||||||
|
</plugin>
|
||||||
|
</plugins>
|
||||||
|
</build>
|
||||||
|
</profile>
|
||||||
|
</profiles>
|
||||||
|
</project>
|
||||||
@@ -0,0 +1,80 @@
|
|||||||
|
package me.hatter.integrations.card;
|
||||||
|
|
||||||
|
import org.cryptomator.integrations.keychain.KeychainAccessException;
|
||||||
|
import org.cryptomator.integrations.keychain.KeychainAccessProvider;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author hatterjiang
|
||||||
|
*/
|
||||||
|
public class CardAccessProvider implements KeychainAccessProvider {
|
||||||
|
|
||||||
|
private static final Logger LOG = LoggerFactory.getLogger(CardAccessProvider.class);
|
||||||
|
|
||||||
|
private CardConfig cardConfig;
|
||||||
|
|
||||||
|
public CardAccessProvider() {
|
||||||
|
try {
|
||||||
|
cardConfig = Utils.loadCardConfig();
|
||||||
|
if (!Utils.checkCardCliReady(cardConfig)) {
|
||||||
|
LOG.error("Check card-cli command failed");
|
||||||
|
cardConfig = null;
|
||||||
|
}
|
||||||
|
} catch (KeychainAccessException e) {
|
||||||
|
cardConfig = null;
|
||||||
|
LOG.error("Load card-cli config failed", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String displayName() {
|
||||||
|
return "CardCli";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isSupported() {
|
||||||
|
return cardConfig != null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isLocked() {
|
||||||
|
// No lock status
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void storePassphrase(String vault, CharSequence password) throws KeychainAccessException {
|
||||||
|
storePassphrase(vault, "Vault", password);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void storePassphrase(String vault, String name, CharSequence password) throws KeychainAccessException {
|
||||||
|
LOG.info("Store password for: " + vault + " / " + name);
|
||||||
|
Utils.storePassword(cardConfig, vault, name, password);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public char[] loadPassphrase(String vault) throws KeychainAccessException {
|
||||||
|
LOG.info("Load password for: " + vault);
|
||||||
|
final String password = Utils.loadPassword(cardConfig, vault);
|
||||||
|
return password.toCharArray();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void deletePassphrase(String vault) throws KeychainAccessException {
|
||||||
|
LOG.info("Delete password for: " + vault);
|
||||||
|
Utils.deletePassword(cardConfig, vault);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void changePassphrase(String vault, CharSequence password) throws KeychainAccessException {
|
||||||
|
changePassphrase(vault, "Vault", password);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void changePassphrase(String vault, String name, CharSequence password) throws KeychainAccessException {
|
||||||
|
LOG.info("Change password for: " + vault + " / " + name);
|
||||||
|
Utils.storePassword(cardConfig, vault, name, password);
|
||||||
|
}
|
||||||
|
}
|
||||||
21
src/main/java/me/hatter/integrations/card/CardConfig.java
Normal file
21
src/main/java/me/hatter/integrations/card/CardConfig.java
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
package me.hatter.integrations.card;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* card-cli config
|
||||||
|
*
|
||||||
|
* @author hatterjiang
|
||||||
|
*/
|
||||||
|
public class CardConfig {
|
||||||
|
/**
|
||||||
|
* OPTIONAL, Encrypt key base path, default "~/.config/cryptomator/card_keys/"
|
||||||
|
*/
|
||||||
|
private String encryptKeyBasePath;
|
||||||
|
|
||||||
|
public String getEncryptKeyBasePath() {
|
||||||
|
return encryptKeyBasePath;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setEncryptKeyBasePath(String encryptKeyBasePath) {
|
||||||
|
this.encryptKeyBasePath = encryptKeyBasePath;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
package me.hatter.integrations.card;
|
||||||
|
|
||||||
|
public class CardHmacDecryptResult {
|
||||||
|
private String plaintext;
|
||||||
|
|
||||||
|
public String getPlaintext() {
|
||||||
|
return plaintext;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setPlaintext(String plaintext) {
|
||||||
|
this.plaintext = plaintext;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
package me.hatter.integrations.card;
|
||||||
|
|
||||||
|
public class CardHmacEncryptResult {
|
||||||
|
private String ciphertext;
|
||||||
|
|
||||||
|
public String getCiphertext() {
|
||||||
|
return ciphertext;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setCiphertext(String ciphertext) {
|
||||||
|
this.ciphertext = ciphertext;
|
||||||
|
}
|
||||||
|
}
|
||||||
285
src/main/java/me/hatter/integrations/card/Utils.java
Normal file
285
src/main/java/me/hatter/integrations/card/Utils.java
Normal file
@@ -0,0 +1,285 @@
|
|||||||
|
package me.hatter.integrations.card;
|
||||||
|
|
||||||
|
import com.google.gson.Gson;
|
||||||
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
import org.cryptomator.integrations.keychain.KeychainAccessException;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
import java.io.*;
|
||||||
|
import java.nio.charset.StandardCharsets;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.Base64;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.concurrent.atomic.AtomicReference;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author hatterjiang
|
||||||
|
*/
|
||||||
|
public class Utils {
|
||||||
|
private static final Logger LOG = LoggerFactory.getLogger(Utils.class);
|
||||||
|
private static final String USER_HOME = System.getProperty("user.home");
|
||||||
|
private static final String DEFAULT_CARD_COMMAND = new File(USER_HOME, "bin/card-cli").getAbsolutePath();
|
||||||
|
private static final File CARD_CONFIG_FILE1 = new File("/etc/cryptomator/card_config.json");
|
||||||
|
private static final File CARD_CONFIG_FILE2 = new File(USER_HOME, ".config/cryptomator/card_config.json");
|
||||||
|
private static final File DEFAULT_ENCRYPTION_KEY_BASE_PATH = new File(USER_HOME, ".config/cryptomator/card_keys/");
|
||||||
|
|
||||||
|
public static boolean isCheckPassphraseStored() {
|
||||||
|
final StackTraceElement stack = getCallerStackTrace();
|
||||||
|
if (stack != null) {
|
||||||
|
return "isPassphraseStored".equals(stack.getMethodName());
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static StackTraceElement getCallerStackTrace() {
|
||||||
|
// org.cryptomator.common.keychain.KeychainManager :: isPassphraseStored
|
||||||
|
final StackTraceElement[] stackTraceElements = Thread.currentThread().getStackTrace();
|
||||||
|
for (int i = 0; i < stackTraceElements.length; i++) {
|
||||||
|
final StackTraceElement stack = stackTraceElements[i];
|
||||||
|
if ("org.cryptomator.common.keychain.KeychainManager".equals(stack.getClassName())) {
|
||||||
|
return stack;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean checkCardCliReady(CardConfig cardConfig) {
|
||||||
|
if (cardConfig == null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
final UtilsCommandResult versionResult = runCardCli(cardConfig, null, "-V");
|
||||||
|
if (versionResult.getExitValue() == 0) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
LOG.warn("Check card-cli not success: " + versionResult);
|
||||||
|
return false;
|
||||||
|
} catch (KeychainAccessException e) {
|
||||||
|
LOG.warn("Check card-cli failed", e);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static CardConfig loadCardConfig() throws KeychainAccessException {
|
||||||
|
final File configFile = getCardConfigFile();
|
||||||
|
if (configFile == null) {
|
||||||
|
return new CardConfig();
|
||||||
|
}
|
||||||
|
final String configJson = readFile(configFile);
|
||||||
|
final CardConfig cardConfig;
|
||||||
|
try {
|
||||||
|
cardConfig = new Gson().fromJson(configJson, CardConfig.class);
|
||||||
|
} catch (Exception e) {
|
||||||
|
throw new KeychainAccessException("Parse card-cli config file: " + configFile + " failed", e);
|
||||||
|
}
|
||||||
|
return cardConfig;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void deletePassword(CardConfig cardConfig, String vault) {
|
||||||
|
final File keyFile = getKeyFile(cardConfig, vault);
|
||||||
|
if (keyFile.exists() && keyFile.isFile()) {
|
||||||
|
keyFile.delete();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String loadPassword(CardConfig cardConfig, String vault) throws KeychainAccessException {
|
||||||
|
final File keyFile = getKeyFile(cardConfig, vault);
|
||||||
|
if (isCheckPassphraseStored()) {
|
||||||
|
LOG.info("Check passphrase stored: " + vault + ", exists: " + keyFile.exists());
|
||||||
|
if (keyFile.exists()) {
|
||||||
|
// this is only for check passphrase stored
|
||||||
|
return "123456";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!keyFile.isFile()) {
|
||||||
|
throw new KeychainAccessException("Password key file: " + keyFile + " not found");
|
||||||
|
}
|
||||||
|
final String encryptedKey = readFile(keyFile);
|
||||||
|
final byte[] password = decrypt(cardConfig, encryptedKey);
|
||||||
|
return new String(password, StandardCharsets.UTF_8);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void storePassword(CardConfig cardConfig, String vault, String name, CharSequence password) throws KeychainAccessException {
|
||||||
|
final String encryptedPassword = encrypt(cardConfig, password.toString().getBytes(StandardCharsets.UTF_8), name);
|
||||||
|
final File keyFile = getKeyFile(cardConfig, vault);
|
||||||
|
writeFile(keyFile, encryptedPassword);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static File getKeyFile(CardConfig cardConfig, String vault) {
|
||||||
|
final StringBuilder sb = new StringBuilder(vault.length());
|
||||||
|
for (char c : vault.toCharArray()) {
|
||||||
|
if ((c >= 'a' && c <= 'z')
|
||||||
|
|| (c >= 'A' && c <= 'Z')
|
||||||
|
|| (c >= '0' && c <= '9')
|
||||||
|
|| (c == '-' || c == '.')) {
|
||||||
|
sb.append(c);
|
||||||
|
} else if (c == '_') {
|
||||||
|
sb.append("__");
|
||||||
|
} else {
|
||||||
|
sb.append('_');
|
||||||
|
final String hex = Integer.toHexString(c);
|
||||||
|
if (hex.length() % 2 != 0) {
|
||||||
|
sb.append('0');
|
||||||
|
}
|
||||||
|
sb.append(hex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return new File(getEncryptKeyBasePath(cardConfig), sb.toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
private static String readFile(File file) throws KeychainAccessException {
|
||||||
|
final StringBuilder sb = new StringBuilder((int) file.length());
|
||||||
|
try (final BufferedReader reader = new BufferedReader(new FileReader(file, StandardCharsets.UTF_8))) {
|
||||||
|
for (int b; ((b = reader.read()) != -1); ) {
|
||||||
|
sb.append((char) b);
|
||||||
|
}
|
||||||
|
return sb.toString();
|
||||||
|
} catch (IOException e) {
|
||||||
|
throw new KeychainAccessException("Read file: " + file + " failed", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void writeFile(File file, String content) throws KeychainAccessException {
|
||||||
|
try (FileOutputStream fos = new FileOutputStream(file)) {
|
||||||
|
fos.write(content.getBytes(StandardCharsets.UTF_8));
|
||||||
|
} catch (Exception e) {
|
||||||
|
throw new KeychainAccessException("Write file: " + file + " failed", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static byte[] decrypt(CardConfig cardConfig, String input) throws KeychainAccessException {
|
||||||
|
final UtilsCommandResult decryptResult = runCardCli(
|
||||||
|
cardConfig,
|
||||||
|
null,
|
||||||
|
"hmac-decrypt",
|
||||||
|
"--ciphertext", input,
|
||||||
|
"--auto-pbe",
|
||||||
|
"--json"
|
||||||
|
);
|
||||||
|
if (decryptResult.getExitValue() != 0) {
|
||||||
|
throw new KeychainAccessException("card-cli decrypt failed: " + decryptResult);
|
||||||
|
}
|
||||||
|
final String resultString = new String(decryptResult.getStdout(), StandardCharsets.UTF_8);
|
||||||
|
final CardHmacDecryptResult result = new Gson().fromJson(resultString, CardHmacDecryptResult.class);
|
||||||
|
return Base64.getDecoder().decode(result.getPlaintext());
|
||||||
|
}
|
||||||
|
|
||||||
|
private static String encrypt(CardConfig cardConfig, byte[] input, String name) throws KeychainAccessException {
|
||||||
|
final UtilsCommandResult encryptResult = runCardCli(
|
||||||
|
cardConfig,
|
||||||
|
null,
|
||||||
|
"hmac-encrypt",
|
||||||
|
"--plaintext", Base64.getEncoder().encodeToString(input),
|
||||||
|
"--with-pbe-encrypt",
|
||||||
|
"--pbe-iteration", "1000000",
|
||||||
|
"--json"
|
||||||
|
);
|
||||||
|
if (encryptResult.getExitValue() != 0) {
|
||||||
|
throw new KeychainAccessException("card-cli encrypt failed: " + encryptResult);
|
||||||
|
}
|
||||||
|
final String resultString = new String(encryptResult.getStdout(), StandardCharsets.UTF_8);
|
||||||
|
final CardHmacEncryptResult result = new Gson().fromJson(resultString, CardHmacEncryptResult.class);
|
||||||
|
return result.getCiphertext();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static UtilsCommandResult runCardCli(CardConfig cardConfig, byte[] input, String... arguments) throws KeychainAccessException {
|
||||||
|
final List<String> commands = new ArrayList<>();
|
||||||
|
commands.add(DEFAULT_CARD_COMMAND);
|
||||||
|
if ((arguments == null) || (arguments.length == 0)) {
|
||||||
|
throw new KeychainAccessException("card-cli not arguments");
|
||||||
|
}
|
||||||
|
commands.addAll(Arrays.asList(arguments));
|
||||||
|
try {
|
||||||
|
final ProcessBuilder processBuilder = new ProcessBuilder(commands);
|
||||||
|
final Process process = processBuilder.start();
|
||||||
|
|
||||||
|
// ----- STD IN -----
|
||||||
|
final AtomicReference<IOException> inThreadException = new AtomicReference<>();
|
||||||
|
final Thread inThread = new Thread(() -> {
|
||||||
|
if ((input != null) && (input.length > 0)) {
|
||||||
|
try (OutputStream processIn = process.getOutputStream()) {
|
||||||
|
processIn.write(input);
|
||||||
|
} catch (IOException e) {
|
||||||
|
inThreadException.set(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
inThread.setDaemon(true);
|
||||||
|
inThread.setName("card-cli-stdin");
|
||||||
|
|
||||||
|
// ----- STD OUT -----
|
||||||
|
final AtomicReference<IOException> outThreadException = new AtomicReference<>();
|
||||||
|
final ByteArrayOutputStream outBaos = new ByteArrayOutputStream();
|
||||||
|
final Thread outThread = getThread(process.getInputStream(), outBaos, outThreadException, "card-cli-stdout");
|
||||||
|
// ----- STD ERR -----
|
||||||
|
final AtomicReference<IOException> errThreadException = new AtomicReference<>();
|
||||||
|
final ByteArrayOutputStream errBaos = new ByteArrayOutputStream();
|
||||||
|
final Thread errThread = getThread(process.getErrorStream(), errBaos, errThreadException, "card-cli-stderr");
|
||||||
|
|
||||||
|
inThread.start();
|
||||||
|
outThread.start();
|
||||||
|
errThread.start();
|
||||||
|
|
||||||
|
inThread.join();
|
||||||
|
if (inThreadException.get() != null) {
|
||||||
|
throw inThreadException.get();
|
||||||
|
}
|
||||||
|
outThread.join();
|
||||||
|
if (outThreadException.get() != null) {
|
||||||
|
throw outThreadException.get();
|
||||||
|
}
|
||||||
|
errThread.join();
|
||||||
|
if (errThreadException.get() != null) {
|
||||||
|
throw errThreadException.get();
|
||||||
|
}
|
||||||
|
final int exitValue = process.waitFor();
|
||||||
|
|
||||||
|
return new UtilsCommandResult(exitValue, outBaos.toByteArray(), errBaos.toByteArray());
|
||||||
|
} catch (Exception e) {
|
||||||
|
throw new KeychainAccessException("Run card-cli command failed: " + commands, e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static Thread getThread(InputStream is, ByteArrayOutputStream outBaos, AtomicReference<IOException> outThreadException, String name) {
|
||||||
|
final Thread outThread = new Thread(() -> {
|
||||||
|
int b;
|
||||||
|
try {
|
||||||
|
while ((b = is.read()) != -1) {
|
||||||
|
outBaos.write(b);
|
||||||
|
}
|
||||||
|
} catch (IOException e) {
|
||||||
|
outThreadException.set(e);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
outThread.setDaemon(true);
|
||||||
|
outThread.setName(name);
|
||||||
|
return outThread;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static File getEncryptKeyBasePath(CardConfig cardConfig) {
|
||||||
|
final File encryptKeyBase;
|
||||||
|
if ((cardConfig != null) && StringUtils.isNoneEmpty(cardConfig.getEncryptKeyBasePath())) {
|
||||||
|
encryptKeyBase = new File(cardConfig.getEncryptKeyBasePath());
|
||||||
|
} else {
|
||||||
|
encryptKeyBase = DEFAULT_ENCRYPTION_KEY_BASE_PATH;
|
||||||
|
}
|
||||||
|
if (encryptKeyBase.isDirectory()) {
|
||||||
|
return encryptKeyBase;
|
||||||
|
}
|
||||||
|
LOG.info("Make dirs: " + encryptKeyBase);
|
||||||
|
encryptKeyBase.mkdirs();
|
||||||
|
return encryptKeyBase;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static File getCardConfigFile() throws KeychainAccessException {
|
||||||
|
for (File configFile : Arrays.asList(CARD_CONFIG_FILE1, CARD_CONFIG_FILE2)) {
|
||||||
|
LOG.info("Check config file: " + configFile + ": " + Arrays.asList(configFile.exists(), configFile.isFile()));
|
||||||
|
if (configFile.exists() && configFile.isFile()) {
|
||||||
|
return configFile;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,40 @@
|
|||||||
|
package me.hatter.integrations.card;
|
||||||
|
|
||||||
|
import java.nio.charset.StandardCharsets;
|
||||||
|
import java.util.Arrays;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author hatterjiang
|
||||||
|
*/
|
||||||
|
public class UtilsCommandResult {
|
||||||
|
private final int exitValue;
|
||||||
|
private final byte[] stdout;
|
||||||
|
private final byte[] stderr;
|
||||||
|
|
||||||
|
public UtilsCommandResult(int exitValue, byte[] stdout, byte[] stderr) {
|
||||||
|
this.exitValue = exitValue;
|
||||||
|
this.stdout = stdout;
|
||||||
|
this.stderr = stderr;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getExitValue() {
|
||||||
|
return exitValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
public byte[] getStdout() {
|
||||||
|
return stdout;
|
||||||
|
}
|
||||||
|
|
||||||
|
public byte[] getStderr() {
|
||||||
|
return stderr;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "CommandResult{" +
|
||||||
|
"exitValue=" + exitValue +
|
||||||
|
", stdout=" + Arrays.toString(stdout) + " (" + new String(stdout, StandardCharsets.UTF_8) + ")" +
|
||||||
|
", stderr=" + Arrays.toString(stderr) + " (" + new String(stderr, StandardCharsets.UTF_8) + ")" +
|
||||||
|
'}';
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
me.hatter.integrations.card.CardAccessProvider
|
||||||
@@ -0,0 +1,20 @@
|
|||||||
|
package me.hatter.integrations.card;
|
||||||
|
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Unit test for simple KeePassXCAccess.
|
||||||
|
*/
|
||||||
|
public class KeePassXCAccessTest
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Rigorous Test :-)
|
||||||
|
*/
|
||||||
|
@Test
|
||||||
|
public void shouldAnswerWithTrue()
|
||||||
|
{
|
||||||
|
assertTrue( true );
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user