Compare commits
11 Commits
34a365960a
...
develop
| Author | SHA1 | Date | |
|---|---|---|---|
| 590f14d101 | |||
| d824b3ef72 | |||
| 5b1c375934 | |||
| 7080ea74fb | |||
| 97d1d6e59b | |||
| 9a858c8993 | |||
| e003288004 | |||
| d2c97bd5e5 | |||
| 1ec2db9583 | |||
| b8cd76b481 | |||
| 7380362280 |
@@ -1 +1,11 @@
|
|||||||
~/.sdkman/candidates/java/21.0.2-graalce/bin/java -agentlib:native-image-agent=config-output-dir=META-INF/native-image -jar target/clj-topt-1.0.32-standalone.jar g TUGOBTEHPSCMUCYAT6UPELNWGE -c
|
#!/usr/bin/env sh
|
||||||
|
|
||||||
|
JAVA_CMD=~/.sdkman/candidates/java/21.0.2-graalce/bin/java
|
||||||
|
UBERJAR=$(realpath --relative-to=. target/clj-totp-cli-*-standalone.jar)
|
||||||
|
|
||||||
|
echo "Using uberjar $UBERJAR"
|
||||||
|
|
||||||
|
$JAVA_CMD -agentlib:native-image-agent=config-output-dir=target/native-image\
|
||||||
|
-jar $UBERJAR import "deleteme" "otpauth-migration://offline?data=CkkKEJ0M4MyHfITKCwCfqPIttjESFHJ1YmVuY2pAMThCMTY5RDVGRjAwGgRTTldMIAEoATACQhMzYjkxMDQxNzI3NzgzNDIzNDYyEAIYASAA"
|
||||||
|
|
||||||
|
java -jar $UBERJAR delete "deleteme"
|
||||||
|
|||||||
@@ -1,4 +0,0 @@
|
|||||||
#!/bin/env sh
|
|
||||||
|
|
||||||
protoc --java_out projects/core/java/protoc/ projects/core/resources/proto/otpauth-migration.proto
|
|
||||||
#javac -cp resources/protobuf-java-3.25.8.jar -d target/classes/proto src/OtpauthMigration.java
|
|
||||||
10
deps.edn
10
deps.edn
@@ -53,7 +53,7 @@
|
|||||||
:ns-default build
|
:ns-default build
|
||||||
:exec-fn jar
|
:exec-fn jar
|
||||||
:exec-args {:subproj "gui"}}
|
:exec-args {:subproj "gui"}}
|
||||||
|
|
||||||
;; Build the three libraries
|
;; Build the three libraries
|
||||||
:build/all {:deps {io.github.clojure/tools.build {:mvn/version "0.10.10"}}
|
:build/all {:deps {io.github.clojure/tools.build {:mvn/version "0.10.10"}}
|
||||||
:replace-deps {clj-totp/core {:local/root "projects/core"}}
|
:replace-deps {clj-totp/core {:local/root "projects/core"}}
|
||||||
@@ -64,5 +64,11 @@
|
|||||||
:uber/cli {:deps {io.github.clojure/tools.build {:mvn/version "0.10.10"}}
|
:uber/cli {:deps {io.github.clojure/tools.build {:mvn/version "0.10.10"}}
|
||||||
:ns-default build
|
:ns-default build
|
||||||
:exec-fn uber
|
:exec-fn uber
|
||||||
:exec-args {:subproj "cli" :main-ns "totp.app"}}}}
|
:exec-args {:subproj "cli" :main-ns "totp.app"}}
|
||||||
|
|
||||||
|
;; Build uber jar for CLI app
|
||||||
|
:uber/gui {:deps {io.github.clojure/tools.build {:mvn/version "0.10.10"}}
|
||||||
|
:ns-default build
|
||||||
|
:exec-fn uber
|
||||||
|
:exec-args {:subproj "gui" :main-ns "totp.app"}}}}
|
||||||
|
|
||||||
|
|||||||
@@ -4,8 +4,10 @@ NATIVE=~/.sdkman/candidates/java/21.0.2-graalce/bin/native-image
|
|||||||
BIN_FILE=totp
|
BIN_FILE=totp
|
||||||
|
|
||||||
echo "Creating uberjar"
|
echo "Creating uberjar"
|
||||||
clojure -T:build uber
|
#clojure -T:uber/cli
|
||||||
UBERJAR=$(realpath --relative-to=target target/clj-totp-*-standalone.jar)
|
UBERJAR=$(realpath --relative-to=target target/clj-totp-cli-*-standalone.jar)
|
||||||
|
|
||||||
|
echo "Using uberjar $UBERJAR"
|
||||||
|
|
||||||
echo "Creating native image"
|
echo "Creating native image"
|
||||||
$NATIVE -jar target/$UBERJAR -o target/$BIN_FILE\
|
$NATIVE -jar target/$UBERJAR -o target/$BIN_FILE\
|
||||||
@@ -17,10 +19,13 @@ $NATIVE -jar target/$UBERJAR -o target/$BIN_FILE\
|
|||||||
--strict-image-heap\
|
--strict-image-heap\
|
||||||
-march=native\
|
-march=native\
|
||||||
-R:MaxHeapSize=10m\
|
-R:MaxHeapSize=10m\
|
||||||
|
--trace-object-instantiation=java.lang.Thread\
|
||||||
--initialize-at-build-time=org.fusesource.jansi.Ansi\
|
--initialize-at-build-time=org.fusesource.jansi.Ansi\
|
||||||
--initialize-at-build-time='org.fusesource.jansi.Ansi$Color'\
|
--initialize-at-build-time='org.fusesource.jansi.Ansi$Color'\
|
||||||
--initialize-at-build-time='org.fusesource.jansi.Ansi$Attribute'\
|
--initialize-at-build-time='org.fusesource.jansi.Ansi$Attribute'\
|
||||||
'--initialize-at-build-time=org.fusesource.jansi.Ansi$1'
|
--initialize-at-build-time='org.fusesource.jansi.Ansi$1'\
|
||||||
|
--initialize-at-run-time=cljc_long.constants__init
|
||||||
|
|
||||||
|
|
||||||
echo "Executable created on target/$BIN_FILE"
|
echo "Executable created on target/$BIN_FILE"
|
||||||
cp target/$BIN_FILE ~/bin
|
cp target/$BIN_FILE ~/bin
|
||||||
@@ -3,7 +3,8 @@
|
|||||||
org.clojure/clojure {:mvn/version "1.12.1"}
|
org.clojure/clojure {:mvn/version "1.12.1"}
|
||||||
cli-matic/cli-matic {:mvn/version "0.5.4"} ;; https://github.com/l3nz/cli-matic
|
cli-matic/cli-matic {:mvn/version "0.5.4"} ;; https://github.com/l3nz/cli-matic
|
||||||
;; Progress bar
|
;; Progress bar
|
||||||
com.github.pmonks/spinner {:mvn/version "2.0.284"}}
|
com.github.pmonks/spinner {:mvn/version "2.0.284"}
|
||||||
|
com.github.clj-easy/graal-build-time {:mvn/version "1.0.5"}}
|
||||||
|
|
||||||
:aliases {;; Execute the app
|
:aliases {;; Execute the app
|
||||||
;:run {:main-opts ["-m" "totp.app"]}
|
;:run {:main-opts ["-m" "totp.app"]}
|
||||||
|
|||||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -1,2 +0,0 @@
|
|||||||
-m
|
|
||||||
kaocha.runner
|
|
||||||
@@ -3,6 +3,8 @@
|
|||||||
mvxcvi/alphabase {:mvn/version "3.0.185"} ;; https://github.com/greglook/alphabase
|
mvxcvi/alphabase {:mvn/version "3.0.185"} ;; https://github.com/greglook/alphabase
|
||||||
;; Protobuf for java
|
;; Protobuf for java
|
||||||
com.google.protobuf/protobuf-java {:mvn/version "3.25.8"}
|
com.google.protobuf/protobuf-java {:mvn/version "3.25.8"}
|
||||||
|
;; Dynamic protobuf
|
||||||
|
com.github.s-expresso/clojobuf {:mvn/version "0.2.1"}
|
||||||
}
|
}
|
||||||
|
|
||||||
:aliases {;; Kaocha runner. You can use the 'kaocha' wrapper located in ~/bin/kaocha
|
:aliases {;; Kaocha runner. You can use the 'kaocha' wrapper located in ~/bin/kaocha
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -1,11 +1,11 @@
|
|||||||
(ns totp.data
|
(ns totp.data
|
||||||
(:require [clojure.edn :as e]
|
(:require [totp.otp-proto :as proto]
|
||||||
|
[clojure.edn :as e]
|
||||||
[clojure.string :as str]
|
[clojure.string :as str]
|
||||||
[clojure.java.io :as io]
|
[clojure.java.io :as io]
|
||||||
[clojure.pprint :as pp]
|
[clojure.pprint :as pp]
|
||||||
[alphabase.base64 :as b64]
|
[alphabase.base64 :as b64]
|
||||||
[alphabase.base32 :as b32])
|
[alphabase.base32 :as b32]))
|
||||||
(:import [protoc OtpauthMigration$MigrationPayload]))
|
|
||||||
|
|
||||||
(defn join-path
|
(defn join-path
|
||||||
"Joins several subpaths using system's path separator (/ un *NIX and \\ in windows)"
|
"Joins several subpaths using system's path separator (/ un *NIX and \\ in windows)"
|
||||||
@@ -207,28 +207,26 @@
|
|||||||
(when (some? url)
|
(when (some? url)
|
||||||
(let [b64-data (second (str/split url #"=" -1))
|
(let [b64-data (second (str/split url #"=" -1))
|
||||||
data-b (b64/decode b64-data)
|
data-b (b64/decode b64-data)
|
||||||
parsed (OtpauthMigration$MigrationPayload/parseFrom data-b)
|
payload (proto/parse-data data-b)
|
||||||
payload (bean (.getOtpParameters parsed 0))
|
;{:keys [name secret name issuer digits algorithm type]} payload
|
||||||
;{:keys [name secret name issuer digitsValue algorithmValue typeValue]} payload
|
secret (:secret payload)
|
||||||
secret-b (:secret payload)
|
|
||||||
secret (b32/encode (.toByteArray secret-b))
|
|
||||||
user (:name payload)
|
user (:name payload)
|
||||||
issuer (:issuer payload)
|
issuer (:issuer payload)
|
||||||
algorithm (case (:algorithmValuei payload) 2 "sha256" 3 "sha512" "sha1")
|
algorithm (:algorithm payload)
|
||||||
digits (case (:digitsValue payload) 2 8 6)
|
digits (:digits payload)
|
||||||
valid-type (= 2 (:typeValue payload))
|
valid-type (= 2 (:type payload))
|
||||||
]
|
]
|
||||||
(println "name:" name "user:" user "issuer:" issuer "digitsValue:" digits "algorithm:" algorithm "valid type?" valid-type)
|
;(println "name:" name "user:" user "issuer:" issuer "digits:" digits "algorithm:" algorithm "valid type?" valid-type)
|
||||||
(if valid-type
|
(if valid-type
|
||||||
(create-app name secret user issuer algorithm digits 30)
|
(create-app name secret user issuer algorithm digits 30)
|
||||||
(println "Invalid OTP type" (:typeValue payload)))
|
(println "Invalid OTP type" (:type payload)))
|
||||||
)))
|
)))
|
||||||
|
|
||||||
(comment
|
(comment
|
||||||
(url-export->app "test"
|
(url-export->app "test"
|
||||||
"otpauth-migration://offline?data=CkkKEJ0M4MyHfITKCwCfqPIttjESFHJ1YmVuY2pAMThCMTY5RDVGRjAwGgRTTldMIAEoATACQhMzYjkxMDQxNzI3NzgzNDIzNDYyEAIYASAA"
|
"otpauth-migration://offline?data=CkkKEJ0M4MyHfITKCwCfqPIttjESFHJ1YmVuY2pAMThCMTY5RDVGRjAwGgRTTldMIAEoATACQhMzYjkxMDQxNzI3NzgzNDIzNDYyEAIYASAA"
|
||||||
)
|
|
||||||
)
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -9,13 +9,19 @@
|
|||||||
;; Original description of the export protocol uses Google's Protocol Buffers
|
;; Original description of the export protocol uses Google's Protocol Buffers
|
||||||
;; https://protobuf.dev/
|
;; https://protobuf.dev/
|
||||||
|
|
||||||
|
(def WIRE_TYPES {:varint 0 ;; Integeres of variable length encoding
|
||||||
|
:i64 1 ;; Fixed 64 bits numbers (integer or decimal)
|
||||||
|
:len 2 ;; Block of bytes with a predefined length
|
||||||
|
:sgroup 3 ;; Group end (deprecated)
|
||||||
|
:egroup 4 ;; Group start (deprecated)
|
||||||
|
:i32 5 ;; Fixed 32 bits number (integer or decimal)
|
||||||
|
})
|
||||||
|
|
||||||
(comment
|
(comment
|
||||||
(let [encoded "CkkKEJ0M4MyHfITKCwCfqPIttjESFHJ1YmVuY2pAMThCMTY5RDVGRjAwGgRTTldMIAEoATACQhMzYjkxMDQxNzI3NzgzNDIzNDYyEAIYASAA"
|
(let [encoded "CkkKEJ0M4MyHfITKCwCfqPIttjESFHJ1YmVuY2pAMThCMTY5RDVGRjAwGgRTTldMIAEoATACQhMzYjkxMDQxNzI3NzgzNDIzNDYyEAIYASAA"
|
||||||
decoded (b64/decode encoded)]
|
decoded (b64/decode encoded)]
|
||||||
(print (hex/encode decoded))
|
(print (hex/encode decoded))
|
||||||
(print (b/to-string decoded))
|
(print (b/to-string decoded))))
|
||||||
)
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
(defn to-fancy-bin
|
(defn to-fancy-bin
|
||||||
@@ -44,42 +50,89 @@
|
|||||||
|
|
||||||
digits = ceil ( log_n ( x + 1 ) )
|
digits = ceil ( log_n ( x + 1 ) )
|
||||||
"
|
"
|
||||||
[x n]
|
[n x]
|
||||||
(case x
|
(case x
|
||||||
nil 0 ;; nill is encoded with zero bytes
|
nil 0 ;; nill is encoded with zero bytes
|
||||||
0 1 ;; One block to zero
|
0 1 ;; One block to zero
|
||||||
9223372036854775807 (len-bits (dec x) n) ;; Beware the overflow!! it's best to lose some precision
|
9223372036854775807 (len-bits n (dec x)) ;; Beware the overflow!! it's best to lose some precision
|
||||||
(when (and (>= x 0) (some? n) (> n 0))
|
(when (and (>= x 0) (some? n) (> n 0))
|
||||||
(long (m/ceil (/ (m/log (inc x)) (m/log (m/pow 2 n))))))))
|
(long (m/ceil (/ (m/log (inc x)) (m/log (m/pow 2 n))))))))
|
||||||
|
|
||||||
(comment
|
(comment
|
||||||
(len-bits 513 8)
|
(len-bits 8 513)
|
||||||
(len-bits Long/MAX_VALUE 8)
|
(len-bits 8 Long/MAX_VALUE)
|
||||||
(len-bits (dec Long/MAX_VALUE) 8)
|
(len-bits 8 (dec Long/MAX_VALUE)))
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
(defn len-bytes
|
(defn len-bytes
|
||||||
"How may bytes are needed to encode this number?"
|
"How may bytes are needed to encode this number?"
|
||||||
[x]
|
[x]
|
||||||
(len-bits x 8))
|
(len-bits 8 x))
|
||||||
|
|
||||||
|
|
||||||
(defn integer>bytes
|
(defn integer>bytes
|
||||||
"Converts an integer to a byte array"
|
"Converts an integer to a byte array"
|
||||||
[x]
|
[x]
|
||||||
(when x (let [len (len-bytes x)
|
(when x (let [len (len-bytes x)
|
||||||
hex-len (* 2 len)]
|
hex-len (* 2 len)]
|
||||||
(hex/decode (String/format (str "%0" hex-len "x") (into-array [x]))))))
|
(hex/decode (String/format (str "%0" hex-len "x") (into-array [x]))))))
|
||||||
|
|
||||||
(comment
|
(comment
|
||||||
(integer>bytes 513)
|
(integer>bytes 513)
|
||||||
10r3
|
10r3
|
||||||
3r10
|
3r10)
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
(defn decimal-to-base
|
(defn euclidean-quot
|
||||||
|
"Euclidean division for integers
|
||||||
|
|
||||||
|
More info: https://en.wikipedia.org/wiki/Euclidean_division
|
||||||
|
"
|
||||||
|
[a b]
|
||||||
|
(when (zero? b)
|
||||||
|
(throw (IllegalArgumentException. "You can't divide by zero!")))
|
||||||
|
(let [b-abs (Math/abs b)
|
||||||
|
r (mod a b-abs)] ;; 0 <= r < |b|
|
||||||
|
(quot (- a r) b) ;; adjusts quotient with the positive remainder
|
||||||
|
))
|
||||||
|
|
||||||
|
|
||||||
|
(defn euclidean-rem
|
||||||
|
"Modulus for euclidean division for integers
|
||||||
|
|
||||||
|
More info: https://en.wikipedia.org/wiki/Euclidean_division
|
||||||
|
"
|
||||||
|
[a b]
|
||||||
|
(when (zero? b)
|
||||||
|
(throw (IllegalArgumentException. "You can't divide by zero!")))
|
||||||
|
(let [b-abs (Math/abs b)]
|
||||||
|
(mod a b-abs);; 0 <= r < |b|
|
||||||
|
))
|
||||||
|
|
||||||
|
|
||||||
|
(defn euclid-div
|
||||||
|
"Euclidean division. Returns quotient and remainder as a map. The remainder is
|
||||||
|
allways a positive number.
|
||||||
|
|
||||||
|
More info: https://en.wikipedia.org/wiki/Euclidean_division"
|
||||||
|
[a b]
|
||||||
|
(when (zero? b)
|
||||||
|
(throw (IllegalArgumentException. "You can't divide by zero!")))
|
||||||
|
(let [b-abs (Math/abs b)
|
||||||
|
r (mod a b-abs) ;; 0 <= r < |b|
|
||||||
|
q (quot (- a r) b)] ;; adjusts quotient with the positive remainder
|
||||||
|
{:q q :r r}))
|
||||||
|
|
||||||
|
|
||||||
|
(comment
|
||||||
|
(euclid-div 7 3)
|
||||||
|
(euclid-div -7 3)
|
||||||
|
(euclid-div 7 -3)
|
||||||
|
(euclid-div -7 -3))
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
(defn decimal->base
|
||||||
"Converts a decimal number to an arbitrary base. Each digit is encoded as an
|
"Converts a decimal number to an arbitrary base. Each digit is encoded as an
|
||||||
integer with value between 0 and base-1.
|
integer with value between 0 and base-1.
|
||||||
|
|
||||||
@@ -99,41 +152,81 @@
|
|||||||
1 / 5 = 0 rem 1
|
1 / 5 = 0 rem 1
|
||||||
|
|
||||||
so, 127 in base 5 is 1002.
|
so, 127 in base 5 is 1002.
|
||||||
|
|
||||||
|
The maximum digits this method can return is 65. Max size for a long is base 2
|
||||||
|
is 64, so if you obtain a result with 65 digits is very probable that the
|
||||||
|
conversion has failed.
|
||||||
|
|
||||||
|
If the number is negative and the base is possitive, we return the conversion
|
||||||
|
of the absolute value. You must take care of the sign in your implementation.
|
||||||
|
|
||||||
|
There are negative bases as -2 that can encode possitive and negative numbers.
|
||||||
"
|
"
|
||||||
([n base]
|
([base n]
|
||||||
(decimal-to-base n base true))
|
(decimal->base base n true))
|
||||||
([n base reverse?]
|
([base n reverse?]
|
||||||
(if (or (nil? n) (nil? base) (zero? n) (zero? base)) ;; Allways [0] for base zero or number zero
|
(if (or (nil? n) (nil? base) (zero? n) (zero? base))
|
||||||
[0]
|
[0] ;; Allways [0] for base zero or number zero
|
||||||
(loop [acc []
|
(loop [acc []
|
||||||
x n]
|
x (if (and (< n 0) (> base 0)) (abs n) n)] ;; If n < 0 and b > 0 => |n|, else n
|
||||||
(if (zero? x)
|
(let [q (euclidean-quot x base)
|
||||||
(vec (if reverse? (reverse acc) acc)) ;; When x is zero, we have finished
|
r (euclidean-rem x base)]
|
||||||
(recur
|
;;(printf "Acc: %s Calculating: %s/%s -> %s rem %s%n" acc x base q r)
|
||||||
(conj acc (rem x base)) ;; Accumulate the remainder
|
(if (or (zero? x) (> (count acc) (inc Long/SIZE))) ;; max digits is 65
|
||||||
(quot x base))))))) ;; Pass the quotient to the next step
|
(vec (if reverse? (reverse acc) acc)) ;; When x is zero, we have finished
|
||||||
|
(recur
|
||||||
|
(conj acc r) ;; Accumulate the remainder
|
||||||
|
q ;; Pass the quotient to the next step
|
||||||
|
)))))))
|
||||||
|
|
||||||
(comment
|
(comment
|
||||||
(decimal-to-base 8 2)
|
(decimal->base 2 8)
|
||||||
2r1000
|
2r1000
|
||||||
)
|
(decimal->base 2 3)
|
||||||
|
|
||||||
|
(letfn [(step [x b name q r]
|
||||||
|
(printf "%s -> %d/%d = %d rem %d%n" name x b q r))
|
||||||
|
(examples [x b exp-q exp-r]
|
||||||
|
(step x b "EXPECTED " exp-q exp-r)
|
||||||
|
(step x b "IEEE " (int (m/IEEE-remainder x b)) (rem x b))
|
||||||
|
(step x b "With rem " (quot x b) (rem x b))
|
||||||
|
(step x b "With mod " (quot x b) (mod x b))
|
||||||
|
(step x b "floor " (m/floor-div x b) (m/floor-mod x b))
|
||||||
|
(step x b "Manual 1 " (int (clojure.math/round (double (/ x b)))) (rem x b))
|
||||||
|
(step x b "Manual 2 " (int (clojure.math/rint (double (/ x b)))) (rem x b))
|
||||||
|
(step x b "Unchecked " (unchecked-divide-int x b) (unchecked-remainder-int x b))
|
||||||
|
(step x b "Euclidean " (euclidean-quot x b) (euclidean-rem x b)))]
|
||||||
|
(examples -3 -2 2 1)
|
||||||
|
(println)
|
||||||
|
(examples 2 -2 -1 0)
|
||||||
|
(println)
|
||||||
|
(examples -1 -2 1 1)
|
||||||
|
(println)
|
||||||
|
(examples 1 -2 0 1)
|
||||||
|
(println)
|
||||||
|
(println)
|
||||||
|
(examples 7 3 2 1)
|
||||||
|
(println)
|
||||||
|
(examples -7 3 -3 2)
|
||||||
|
(println)
|
||||||
|
(examples 7 -3 -2 1)
|
||||||
|
(println)
|
||||||
|
(examples -7 -3 3 2)))
|
||||||
|
|
||||||
|
|
||||||
(defn base-to-decimal
|
(defn base->decimal
|
||||||
"Converts from an array with values in an arbitrary base into decimal values"
|
"Converts from an array with values in an arbitrary base into decimal values"
|
||||||
[n base]
|
[base n]
|
||||||
(if (or (nil? n) (nil? base) (zero? (count n)))
|
(if (or (nil? n) (nil? base) (zero? (count n)))
|
||||||
0
|
0
|
||||||
(long (reduce-kv
|
(long (reduce-kv
|
||||||
(fn [acc k v]
|
(fn [acc k v]
|
||||||
(+ acc (* v (m/pow base k))))
|
(+ acc (* v (m/pow base k))))
|
||||||
0 (vec (reverse n))))))
|
0 (vec (reverse n))))))
|
||||||
|
|
||||||
(comment
|
(comment
|
||||||
(reduce-kv #(+ %1 (* %3 (m/pow 2 %2))) 0 [1 0 0 0]) ;; backwards!
|
(reduce-kv #(+ %1 (* %3 (m/pow 2 %2))) 0 [1 0 0 0]) ;; backwards!
|
||||||
|
(base->decimal 2 [1 0 0 0]))
|
||||||
(base-to-decimal [1 0 0 0] 2)
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
(defn int->varint
|
(defn int->varint
|
||||||
@@ -151,7 +244,7 @@
|
|||||||
The result is a byte array.
|
The result is a byte array.
|
||||||
"
|
"
|
||||||
[x]
|
[x]
|
||||||
(let [b128 (decimal-to-base x 128 false)]
|
(let [b128 (decimal->base 128 x false)]
|
||||||
(byte-array (conj
|
(byte-array (conj
|
||||||
(vec (map #(bit-or 2r10000000 %) (butlast b128)))
|
(vec (map #(bit-or 2r10000000 %) (butlast b128)))
|
||||||
(bit-and 2r01111111 (peek b128))))))
|
(bit-and 2r01111111 (peek b128))))))
|
||||||
@@ -174,7 +267,8 @@
|
|||||||
00000000 10010110 -> fill the bytes
|
00000000 10010110 -> fill the bytes
|
||||||
"
|
"
|
||||||
[x]
|
[x]
|
||||||
(base-to-decimal (reverse (map #(bit-and 2r01111111 %) x)) 128))
|
(base->decimal 128 (reverse (map #(bit-and 2r01111111 %) x))))
|
||||||
|
|
||||||
|
|
||||||
(comment
|
(comment
|
||||||
;; 150
|
;; 150
|
||||||
@@ -183,38 +277,109 @@
|
|||||||
(to-fancy-bin (reverse (map #(bit-and 2r01111111 %) [-106, 1])))
|
(to-fancy-bin (reverse (map #(bit-and 2r01111111 %) [-106, 1])))
|
||||||
(varint->int [-106, 1])
|
(varint->int [-106, 1])
|
||||||
|
|
||||||
;; Long/MAX_VALUE
|
|
||||||
(to-fancy-bin (map #(bit-and 2r01111111 %) [-1, -1, -1, -1, -1, -1, -1, -1, 128]))
|
|
||||||
(varint->int [-2, -1, -1, -1, -1, -1, -1, -1, 127])
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
(comment
|
|
||||||
(hex/decode (String/format "%08x" (into-array [1023])))
|
|
||||||
|
|
||||||
(to-fancy-bin [150])
|
|
||||||
|
|
||||||
(to-fancy-bin (int->varint 150))
|
|
||||||
(to-fancy-bin (int->varint 151))
|
|
||||||
|
|
||||||
(to-fancy-hex (int->varint 150))
|
|
||||||
(to-fancy-hex (int->varint 151) 4)
|
|
||||||
|
|
||||||
(varint->int [-106, 1])
|
(varint->int [-106, 1])
|
||||||
(varint->int [-105, 1])
|
(varint->int [-105, 1])
|
||||||
|
|
||||||
(to-fancy-bin (int->varint Long/MAX_VALUE))
|
;; Long/MAX_VALUE
|
||||||
(to-fancy-bin (int->varint (dec Long/MAX_VALUE)))
|
(to-fancy-bin (map #(bit-and 2r01111111 %) [-1, -1, -1, -1, -1, -1, -1, -1, 128]))
|
||||||
|
(varint->int [-2, -1, -1, -1, -1, -1, -1, -1, 127]))
|
||||||
|
|
||||||
(to-fancy-hex (int->varint (dec Long/MAX_VALUE)))
|
|
||||||
|
|
||||||
(varint->int [-2, -1, -1, -1, -1, -1, -1, -1, 127])
|
(defn more-blocks?
|
||||||
|
"True if the MSB bit is 1"
|
||||||
|
[b]
|
||||||
|
(when b
|
||||||
|
(< 0 (bit-and 2r10000000 b))))
|
||||||
|
|
||||||
(to-fancy-bin [2r10010110 2r00000001])
|
(comment
|
||||||
|
(bit-and 2r10000000 2r10000001)
|
||||||
[2r10010110 2r00000001]
|
(bit-and 2r10000000 2r00000001)
|
||||||
[2r0010110 2r0000001]
|
( more-blocks? 2r10000001)
|
||||||
|
(more-blocks? 2r00000001)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
(defn extract-varint-blocks
|
||||||
|
"Group varints in a byte array"
|
||||||
|
[bytes]
|
||||||
|
(loop [acc [] ;; Groups of varints
|
||||||
|
group [] ;; Current varint
|
||||||
|
r bytes] ;; Current tested byte
|
||||||
|
(if (empty? r) ;; Final condition: no more bytes to test
|
||||||
|
(if ((complement empty?) group)
|
||||||
|
(conj acc group) ;; Return acc with the last group added if not empty
|
||||||
|
acc) ;; if empty, return acc
|
||||||
|
(if (more-blocks? (first r))
|
||||||
|
;; If more blocks remains:
|
||||||
|
(recur acc
|
||||||
|
(conj group (first r)) ;; add current byte to current group
|
||||||
|
(next r))
|
||||||
|
;; If it's last in varint:
|
||||||
|
(recur (->> (first r)
|
||||||
|
(conj group) ;; add byte to group
|
||||||
|
(conj acc)) ;; add group to accumulator
|
||||||
|
[] ;; and start a new empty group
|
||||||
|
(next r))))))
|
||||||
|
|
||||||
|
(comment
|
||||||
|
(extract-varint-blocks [2r11111111 2r01111111, 2r10000001 2r10101001 2r00000001, 2r00000111])
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
(defn extract-varints
|
||||||
|
"Group varints in an byte array and convert them to decimal"
|
||||||
|
[bytes]
|
||||||
|
(map varint->int (extract-varint-blocks bytes)))
|
||||||
|
|
||||||
|
(comment
|
||||||
|
(extract-varints [2r11111111 2r01111111, 2r10000001 2r10101001 2r00000001, 2r00000111])
|
||||||
|
|
||||||
|
(varint->int [2r11111111 2r01111111])
|
||||||
|
(varint->int [2r10000001 2r10101001 2r00000001])
|
||||||
|
(varint->int [2r00000111])
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
(defn bytes->len-type
|
||||||
|
"Prepend byte array with length in varint format"
|
||||||
|
[bytes]
|
||||||
|
(concat (int->varint (count bytes))
|
||||||
|
bytes))
|
||||||
|
|
||||||
|
(comment
|
||||||
|
(to-fancy-hex (bytes->len-type (.getBytes "testing")))
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
(defn pack-bytes-as-tlv
|
||||||
|
"Pack the value as TLV.
|
||||||
|
|
||||||
|
Type can one of those 6 IDs:
|
||||||
|
ID Name Used For
|
||||||
|
0 VARINT int32, int64, uint32, uint64, sint32, sint64, bool, enum
|
||||||
|
1 I64 fixed64, sfixed64, double
|
||||||
|
2 LEN string, bytes, embedded messages, packed repeated fields
|
||||||
|
3 SGROUP group start (deprecated)
|
||||||
|
4 EGROUP group end (deprecated)
|
||||||
|
5 I32 fixed32, sfixed32, float
|
||||||
|
"
|
||||||
|
([{:keys [field type value]}]
|
||||||
|
(pack-bytes-as-tlv field type value))
|
||||||
|
([field-number type value]
|
||||||
|
(let [field-displaced (bit-shift-left field-number 3)
|
||||||
|
tag (int->varint (bit-or field-displaced type))]
|
||||||
|
(concat tag value))))
|
||||||
|
|
||||||
|
|
||||||
|
(defn unpack-tlv-bytes
|
||||||
|
"Returns a map with 3 pairs:
|
||||||
|
- :field is the field number
|
||||||
|
- :type is one of the values of WIRE_TYPES
|
||||||
|
- :value is the byte array with the payload"
|
||||||
|
[packed]
|
||||||
|
(let [first-byte (bit-and 2r01111111 (first packed)) ;; bye bye, MSB
|
||||||
|
type (bit-and 2r00000111 first-byte)
|
||||||
|
field-number (bit-shift-right first-byte 3)]
|
||||||
|
{:field field-number :type type :value (rest packed)}))
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
45
projects/core/src/totp/otp_proto.clj
Normal file
45
projects/core/src/totp/otp_proto.clj
Normal file
@@ -0,0 +1,45 @@
|
|||||||
|
(ns totp.otp-proto
|
||||||
|
(:require [clojobuf.core :refer [protoc decode]]
|
||||||
|
[alphabase.base64 :as b64]
|
||||||
|
[alphabase.base32 :as b32]))
|
||||||
|
|
||||||
|
|
||||||
|
;; Where lookup for proto files
|
||||||
|
(def registry (protoc ["resourcse/proto/"
|
||||||
|
"projects/core/resources/proto/"]
|
||||||
|
["otpauth-migration.proto"]))
|
||||||
|
|
||||||
|
|
||||||
|
(defn parse-data
|
||||||
|
[binary-data]
|
||||||
|
(let [decoded (decode registry :MigrationPayload binary-data)
|
||||||
|
msg (get-in decoded [:otp_parameters 0])]
|
||||||
|
;(println "Decoded:" msg)
|
||||||
|
(when msg
|
||||||
|
{:secret (b32/encode (:secret msg))
|
||||||
|
:name (:name msg)
|
||||||
|
:issuer (:issuer msg)
|
||||||
|
:algorithm (case (:algorithm msg)
|
||||||
|
:ALGORITHM_SHA256 "sha256"
|
||||||
|
:ALGORITHM_SHA512 "sha512"
|
||||||
|
:ALGORITHM_MD5 "md5"
|
||||||
|
"sha1") ;; sha1 by default
|
||||||
|
:digits (case (:digits msg)
|
||||||
|
:DIGIT_COUNT_EIGHT 8
|
||||||
|
6) ;; 6 digits by default
|
||||||
|
:type (case (:type msg)
|
||||||
|
:OTP_TYPE_UNSPECIFIED 0
|
||||||
|
:OTP_TYPE_HOTP 1
|
||||||
|
:OTP_TYPE_TOTP 2) ;; Only TOTP is supported
|
||||||
|
})))
|
||||||
|
|
||||||
|
|
||||||
|
(comment
|
||||||
|
(let [b64-data "CkkKEJ0M4MyHfITKCwCfqPIttjESFHJ1YmVuY2pAMThCMTY5RDVGRjAwGgRTTldMIAEoATACQhMzYjkxMDQxNzI3NzgzNDIzNDYyEAIYASAA"
|
||||||
|
bin-data (b64/decode b64-data)
|
||||||
|
decoded (decode registry :MigrationPayload bin-data)]
|
||||||
|
;(get-in decoded [:otp_parameters 0])
|
||||||
|
(parse-data bin-data)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -1,8 +0,0 @@
|
|||||||
#!/usr/bin/env sh
|
|
||||||
|
|
||||||
JAVA_EXECUTABLE=java
|
|
||||||
UBER_JAR=$(realpath clj-totp-*-standalone.jar)
|
|
||||||
OPTS="-Xms256m -Xmx256m -client -Dclojure.spec.skip-macros=true"
|
|
||||||
|
|
||||||
|
|
||||||
$JAVA_EXECUTABLE $OPTS -jar $UBER_JAR $@
|
|
||||||
@@ -11,14 +11,14 @@
|
|||||||
|
|
||||||
(deftest len-bits-test
|
(deftest len-bits-test
|
||||||
(testing "Check required number of blocks to encode a number in n bits"
|
(testing "Check required number of blocks to encode a number in n bits"
|
||||||
(is (nil? (len-bits 10 nil)))
|
(is (nil? (len-bits nil 10)))
|
||||||
(is (= 0 (len-bits nil 10)))
|
(is (= 0 (len-bits 10 nil)))
|
||||||
(is (= 1 (len-bits 1 2)))
|
(is (= 1 (len-bits 2 1)))
|
||||||
(is (= 2 (len-bits 10 2)))
|
(is (= 2 (len-bits 2 10)))
|
||||||
(is (= 2 (len-bits 15 2)))
|
(is (= 2 (len-bits 2 15)))
|
||||||
(is (= 3 (len-bits 16 2)))
|
(is (= 3 (len-bits 2 16)))
|
||||||
(is (= 1 (len-bits 255 8)))
|
(is (= 1 (len-bits 8 255)))
|
||||||
(is (= 2 (len-bits 255 7)))
|
(is (= 2 (len-bits 7 255)))
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -49,49 +49,40 @@
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
(deftest decimal-to-base-test
|
(deftest decimal->base-test
|
||||||
(testing "Convert from decimal base to an arbitrary base"
|
(testing "Convert from decimal base to an arbitrary base"
|
||||||
(is (= [0] (decimal-to-base 10 nil)))
|
(is (= [0] (decimal->base nil 10)))
|
||||||
(is (= [0] (decimal-to-base nil 10)))
|
(is (= [0] (decimal->base 10 nil)))
|
||||||
(is (= [0] (decimal-to-base 0 2)))
|
(is (= [0] (decimal->base 2 0)))
|
||||||
(is (= [0] (decimal-to-base 2 0)))
|
(is (= [0] (decimal->base 0 2)))
|
||||||
(is (= [1 0 0 0] (decimal-to-base 8 2)))
|
(is (= [1 0 0 0] (decimal->base 2 8)))
|
||||||
(is (= [2 2] (decimal-to-base 8 3)))
|
(is (= [2 2] (decimal->base 3 8)))
|
||||||
(is (= [2 0] (decimal-to-base 8 4)))
|
(is (= [2 0] (decimal->base 4 8)))
|
||||||
(is (= [1 3] (decimal-to-base 8 5)))
|
(is (= [1 3] (decimal->base 5 8)))
|
||||||
(is (= [3 1] (decimal-to-base 8 5 false)))
|
(is (= [3 1] (decimal->base 5 8 false)))
|
||||||
(is (= [0] (decimal-to-base 0 5)))
|
(is (= [0] (decimal->base 5 0)))
|
||||||
)
|
|
||||||
)
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
(deftest base-to-decimal-test
|
(deftest base->decimal-test
|
||||||
(testing "Convert from arbitrary base to decimal"
|
(testing "Convert from arbitrary base to decimal"
|
||||||
(is (zero? (base-to-decimal nil 2)))
|
(is (zero? (base->decimal 2 nil)))
|
||||||
(is (zero? (base-to-decimal [] 2)))
|
(is (zero? (base->decimal 2 [])))
|
||||||
(is (zero? (base-to-decimal [1] nil)))
|
(is (zero? (base->decimal nil [1])))
|
||||||
(is (= 8 (base-to-decimal [1 0 0 0] 2)))
|
(is (= 8 (base->decimal 2 [1 0 0 0])))
|
||||||
(is (= 8 (base-to-decimal [2 2] 3)))
|
(is (= 8 (base->decimal 3 [2 2])))
|
||||||
(is (= 8 (base-to-decimal [2 0] 4)))
|
(is (= 8 (base->decimal 4 [2 0])))
|
||||||
(is (= 8 (base-to-decimal [1 3] 5)))
|
(is (= 8 (base->decimal 5 [1 3])))
|
||||||
)
|
|
||||||
)
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
(deftest decimal-base-decimal-test
|
(deftest decimal->base-decimal-test
|
||||||
(testing "Check if convert from decimal to a base and back preserves the original number"
|
(testing "Check if convert from decimal to a base and back preserves the original number"
|
||||||
(is (= 8 (base-to-decimal (decimal-to-base 8 2) 2)))
|
(is (= 8 (base->decimal 2 (decimal->base 2 8))))
|
||||||
(is (= 127 (base-to-decimal (decimal-to-base 127 2) 2)))
|
(is (= 127 (base->decimal 2 (decimal->base 2 127))))
|
||||||
(is (= 417 (base-to-decimal (decimal-to-base 417 13) 13)))
|
(is (= 417 (base->decimal 13 (decimal->base 13 417))))
|
||||||
))
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
(deftest int->varint-test
|
|
||||||
(testing "Convert from integer number (int, long, byte, etc) to varint"
|
|
||||||
(is (Arrays/equals (byte-array [0]) (int->varint nil)))
|
|
||||||
(is (Arrays/equals (byte-array [0]) (int->varint 0)))
|
|
||||||
(is (Arrays/equals (byte-array [2r10010110 2r00000001]) (int->varint 150)))
|
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -120,5 +111,39 @@
|
|||||||
(testing "Convert from int to varint and back to int"
|
(testing "Convert from int to varint and back to int"
|
||||||
(is (= 150 (varint->int (int->varint 150))))
|
(is (= 150 (varint->int (int->varint 150))))
|
||||||
(is (= 151 (varint->int (int->varint 151))))
|
(is (= 151 (varint->int (int->varint 151))))
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
(deftest more-blocks?-test
|
||||||
|
(testing "Check if there are more blocks in a varint type"
|
||||||
|
(is (nil? (more-blocks? nil)))
|
||||||
|
(is (true? (more-blocks? 2r10000001)))
|
||||||
|
(is (true? (more-blocks? 2r11111111)))
|
||||||
|
(is (false? (more-blocks? 2r00000001)))
|
||||||
|
(is (false? (more-blocks? 2r01111111)))
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
(deftest extract-varint-blocks-test
|
||||||
|
(testing "Group varints"
|
||||||
|
(is (empty? (extract-varint-blocks nil)))
|
||||||
|
(is (empty? (extract-varint-blocks [])))
|
||||||
|
(is (= [[2r00000111]] (extract-varint-blocks [2r00000111])))
|
||||||
|
(is (= [[2r00000111] [2r00000111]] (extract-varint-blocks [2r00000111 2r00000111])))
|
||||||
|
(is (= [[2r11111111 2r01111111] [2r10000001 2r10101001 2r00000001] [2r00000111]] (extract-varint-blocks [2r11111111 2r01111111, 2r10000001 2r10101001 2r00000001, 2r00000111])))
|
||||||
|
(is (= [[2r11111111 2r01111111] [2r10000001 2r10101001 2r00000001] [2r10000111]] (extract-varint-blocks [2r11111111 2r01111111, 2r10000001 2r10101001 2r00000001, 2r10000111])))
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
(deftest extract-varints-test
|
||||||
|
(testing "bytes with varints to decimal"
|
||||||
|
(is (empty? (extract-varints nil)))
|
||||||
|
(is (empty? (extract-varints [])))
|
||||||
|
(is (= [7] (extract-varints [2r00000111])))
|
||||||
|
(is (= [7 7] (extract-varints [2r00000111 2r00000111])))
|
||||||
|
(is (= [16383 21633 7] (extract-varints [2r11111111 2r01111111, 2r10000001 2r10101001 2r00000001, 2r00000111])))
|
||||||
|
(is (= [16383 21633 7] (extract-varints [2r11111111 2r01111111, 2r10000001 2r10101001 2r00000001, 2r10000111])))
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
:deps {;;org.clojure/clojure {:mvn/version "1.12.1"}
|
:deps {;;org.clojure/clojure {:mvn/version "1.12.1"}
|
||||||
cli-matic/cli-matic {:mvn/version "0.5.4"} ;; https://github.com/l3nz/cli-matic
|
cli-matic/cli-matic {:mvn/version "0.5.4"} ;; https://github.com/l3nz/cli-matic
|
||||||
;; GUI
|
;; GUI
|
||||||
seesaw/seesaw {:mvn/version "1.5.0"}}
|
seesaw/seesaw {:mvn/version "1.5.0"}
|
||||||
|
com.github.clj-easy/graal-build-time {:mvn/version "1.0.5"}}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -7,29 +7,8 @@
|
|||||||
[seesaw.mig :refer :all]
|
[seesaw.mig :refer :all]
|
||||||
[seesaw.clipboard :as cp]
|
[seesaw.clipboard :as cp]
|
||||||
[seesaw.dev :refer :all])
|
[seesaw.dev :refer :all])
|
||||||
(:import [java.util Date TimerTask Timer]))
|
(:import [java.util Date TimerTask Timer])
|
||||||
|
(:gen-class))
|
||||||
|
|
||||||
|
|
||||||
(defn content-test
|
|
||||||
[]
|
|
||||||
(let [choose (fn [e] (alert "I should open a file chooser"))]
|
|
||||||
(flow-panel
|
|
||||||
:items ["File" [:fill-h 5]
|
|
||||||
(text (System/getProperty "user.dir")) [:fill-h 5]
|
|
||||||
(action :handler choose :name "...")])))
|
|
||||||
|
|
||||||
|
|
||||||
(defn content-test2
|
|
||||||
[name category date comment]
|
|
||||||
(mig-panel
|
|
||||||
:constraints ["wrap 2"
|
|
||||||
"[shrink 0]20px[200, grow, fill]"
|
|
||||||
"[shrink 0]5px[]"]
|
|
||||||
:items [["name:"] [(text (or name ""))]
|
|
||||||
["category:"] [(text (or category ""))]
|
|
||||||
["date:"] [(text (or date ""))]
|
|
||||||
["comment:"] [(text (or comment ""))]]))
|
|
||||||
|
|
||||||
|
|
||||||
(defn copy-handler
|
(defn copy-handler
|
||||||
@@ -37,36 +16,34 @@
|
|||||||
[field-id e]
|
[field-id e]
|
||||||
(let [b-name (str "#" field-id)
|
(let [b-name (str "#" field-id)
|
||||||
b-obj (select (to-root e) [(keyword b-name)])
|
b-obj (select (to-root e) [(keyword b-name)])
|
||||||
b-text (config b-obj :text)]
|
b-text (config b-obj :text)]
|
||||||
(println "Copying text value: " b-text)
|
(println "Copying text value: " b-text)
|
||||||
(cp/contents! b-text)
|
(cp/contents! b-text)))
|
||||||
))
|
|
||||||
|
|
||||||
|
|
||||||
(defn make-otp-list
|
(defn make-otp-list
|
||||||
"Make panel with OTPs"
|
"Make panel with OTPs"
|
||||||
[]
|
[]
|
||||||
(mig-panel
|
(scrollable
|
||||||
:constraints ["wrap 3"
|
(mig-panel
|
||||||
"[shrink 0]20px[200, grow, fill]10px[shrink 0]"]
|
:constraints ["wrap 3"
|
||||||
:items (let [apps (with-config (filter some? #_{:clj-kondo/ignore [:unresolved-symbol]} cfg))
|
"[shrink 0]20px[200, grow, fill]10px[shrink 0]"]
|
||||||
]
|
:items (let [apps (with-config (filter some? #_{:clj-kondo/ignore [:unresolved-symbol]} cfg))]
|
||||||
(reduce (fn [acc a]
|
(reduce (fn [acc a]
|
||||||
(let [{:keys [name secret algorithm digits period]} a
|
(let [{:keys [name secret algorithm digits period]} a
|
||||||
field-id (str "field-totp-" name)]
|
field-id (str "field-totp-" name)]
|
||||||
(-> acc
|
(-> acc
|
||||||
(conj [name])
|
(conj [name])
|
||||||
(conj [(text :text (get-otp secret algorithm digits period)
|
(conj [(text :text (get-otp secret algorithm digits period)
|
||||||
:editable? false
|
:editable? false
|
||||||
:id field-id)])
|
:id field-id)])
|
||||||
(conj [(action :name "copy"
|
(conj [(action :name "copy"
|
||||||
:handler (partial copy-handler field-id)
|
:handler (partial copy-handler field-id)
|
||||||
:command (str "cmd-" name))]))))
|
:command (str "cmd-" name))]))))
|
||||||
[] apps))))
|
[] apps)))))
|
||||||
|
|
||||||
(comment
|
(comment
|
||||||
(make-otp-list)
|
(make-otp-list))
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
(defn make-time-bar
|
(defn make-time-bar
|
||||||
@@ -76,21 +53,47 @@
|
|||||||
:hgap 5
|
:hgap 5
|
||||||
:center (progress-bar :id "timer-bar"
|
:center (progress-bar :id "timer-bar"
|
||||||
:value init-val
|
:value init-val
|
||||||
:max 30)
|
:max 30
|
||||||
|
:paint-string? true)
|
||||||
:east (text :id "timer-text"
|
:east (text :id "timer-text"
|
||||||
:text init-val
|
:text init-val
|
||||||
:editable? false
|
:editable? false
|
||||||
:columns 2
|
:columns 2
|
||||||
:halign :right)
|
:halign :right)))
|
||||||
))
|
|
||||||
|
|
||||||
|
(defn make-add-frame
|
||||||
|
[parent]
|
||||||
|
(frame :title "Add new TOTP"
|
||||||
|
:minimum-size [320 :by 200]
|
||||||
|
:size [320 :by 220]
|
||||||
|
:on-close :dispose
|
||||||
|
:content (border-panel
|
||||||
|
:center (mig-panel
|
||||||
|
:constraints ["wrap 2"
|
||||||
|
"[shrink 0]20px[200, grow, fill]"]
|
||||||
|
:items [["Name"] [(text :id "add-name" :columns 32)]
|
||||||
|
["Secret (B32)"] [(text :id "add-secret" :columns 32)]
|
||||||
|
["User (optional)"] [(text :id "add-user" :columns 32)]
|
||||||
|
["Issuer (optional)"] [(text :id "add-issuer" :columns 32)]
|
||||||
|
["Algorithm"] [(combobox :model ["sha1" "sha256" "sha512"])]
|
||||||
|
["Digits"] [(combobox :model ["6" "8"])]])
|
||||||
|
:south (flow-panel :align :right :items [(action :name "Cancel")
|
||||||
|
(action :name "Add")]))))
|
||||||
|
|
||||||
|
|
||||||
|
(defn make-main-buttons
|
||||||
|
[]
|
||||||
|
(flow-panel :align :right
|
||||||
|
:items ["button a" "button b"]))
|
||||||
|
|
||||||
|
|
||||||
(defn make-frame-content
|
(defn make-frame-content
|
||||||
[]
|
[]
|
||||||
(border-panel :hgap 10 :vgap 10
|
(border-panel :hgap 10 :vgap 10
|
||||||
:center (make-otp-list)
|
:center (make-otp-list)
|
||||||
:north (make-time-bar (int(/ (calculate-offset-millis 30) 1000)))
|
:north (make-time-bar (int (/ (calculate-offset-millis 30) 1000)))
|
||||||
;:south "SOUTH"
|
:south (make-main-buttons)
|
||||||
;:east "EAST"
|
;:east "EAST"
|
||||||
;:west "WEST"
|
;:west "WEST"
|
||||||
))
|
))
|
||||||
@@ -106,6 +109,7 @@
|
|||||||
:on-close :dispose))
|
:on-close :dispose))
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
(defn update-totps
|
(defn update-totps
|
||||||
"Update all totps"
|
"Update all totps"
|
||||||
[root]
|
[root]
|
||||||
@@ -115,7 +119,7 @@
|
|||||||
field-id (str "field-totp-" name)
|
field-id (str "field-totp-" name)
|
||||||
field (select root [(keyword (str "#" field-id))])
|
field (select root [(keyword (str "#" field-id))])
|
||||||
current-otp (get-otp secret algorithm digits period)]
|
current-otp (get-otp secret algorithm digits period)]
|
||||||
(println "Updating" field-id "with otp" current-otp)
|
;;(println "Updating" field-id "with otp" current-otp)
|
||||||
(config! field :text current-otp)))))
|
(config! field :text current-otp)))))
|
||||||
|
|
||||||
|
|
||||||
@@ -124,13 +128,12 @@
|
|||||||
(let [time-bar (select root [:#timer-bar])
|
(let [time-bar (select root [:#timer-bar])
|
||||||
time-text (select root [:#timer-text])
|
time-text (select root [:#timer-text])
|
||||||
offset (inc (int (/ (calculate-offset-millis 30) 1000)))]
|
offset (inc (int (/ (calculate-offset-millis 30) 1000)))]
|
||||||
(println "Updating at at" (System/currentTimeMillis))
|
;;(println "Updating at at" (System/currentTimeMillis))
|
||||||
(config! time-bar :value offset)
|
(config! time-bar :value offset)
|
||||||
(config! time-text :text offset)
|
(config! time-text :text offset)
|
||||||
(when (= 1 offset)
|
(when (= 1 offset)
|
||||||
(println "update TOTP")
|
;;(println "update TOTP")
|
||||||
(update-totps root))
|
(update-totps root))))
|
||||||
))
|
|
||||||
|
|
||||||
|
|
||||||
(defn start-updater
|
(defn start-updater
|
||||||
@@ -142,8 +145,8 @@
|
|||||||
(proxy [TimerTask] []
|
(proxy [TimerTask] []
|
||||||
(run [] (update-progress root)))
|
(run [] (update-progress root)))
|
||||||
delay 1000))
|
delay 1000))
|
||||||
(println "Now" now "Delay" delay)
|
(println "Now" now "Delay" delay)))
|
||||||
))
|
|
||||||
|
|
||||||
|
|
||||||
(defn -main [& args]
|
(defn -main [& args]
|
||||||
@@ -152,6 +155,7 @@
|
|||||||
(-> (make-frame)
|
(-> (make-frame)
|
||||||
pack!
|
pack!
|
||||||
show!
|
show!
|
||||||
|
(make-add-frame)
|
||||||
start-updater))
|
start-updater))
|
||||||
(println "Gui started"))
|
(println "Gui started"))
|
||||||
|
|
||||||
@@ -163,4 +167,6 @@
|
|||||||
(show-options (frame))
|
(show-options (frame))
|
||||||
(show-options (text))
|
(show-options (text))
|
||||||
|
|
||||||
)
|
(-> (make-add-frame nil)
|
||||||
|
(pack!)
|
||||||
|
(show!)))
|
||||||
|
|||||||
1812
reflect_config.json
1812
reflect_config.json
File diff suppressed because it is too large
Load Diff
270
reflect_config.json.bak
Normal file
270
reflect_config.json.bak
Normal file
@@ -0,0 +1,270 @@
|
|||||||
|
[
|
||||||
|
{
|
||||||
|
"name": "com.sun.crypto.provider.HmacSHA1",
|
||||||
|
"methods": [
|
||||||
|
{
|
||||||
|
"name": "<init>",
|
||||||
|
"parameterTypes": []
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "java.lang.reflect.Method",
|
||||||
|
"methods": [
|
||||||
|
{
|
||||||
|
"name": "canAccess",
|
||||||
|
"parameterTypes": [
|
||||||
|
"java.lang.Object"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "java.util.Arrays",
|
||||||
|
"allDeclaredClasses": true,
|
||||||
|
"allPublicClasses": true,
|
||||||
|
"queryAllPublicMethods": true,
|
||||||
|
"methods": [
|
||||||
|
{
|
||||||
|
"name": "copyOfRange",
|
||||||
|
"parameterTypes": [
|
||||||
|
"byte[]",
|
||||||
|
"int",
|
||||||
|
"int"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "java.util.Timer",
|
||||||
|
"queryAllPublicMethods": true,
|
||||||
|
"methods": [
|
||||||
|
{
|
||||||
|
"name": "scheduleAtFixedRate",
|
||||||
|
"parameterTypes": [
|
||||||
|
"java.util.TimerTask",
|
||||||
|
"long",
|
||||||
|
"long"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "java.util.concurrent.locks.Lock"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "java.util.concurrent.locks.ReentrantLock"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "rubberbuf.ast_postprocess$eval194",
|
||||||
|
"methods": [
|
||||||
|
{
|
||||||
|
"name": "<init>",
|
||||||
|
"parameterTypes": []
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "rubberbuf.ast_postprocess$eval209",
|
||||||
|
"methods": [
|
||||||
|
{
|
||||||
|
"name": "<init>",
|
||||||
|
"parameterTypes": []
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "rubberbuf.ast_postprocess$eval224",
|
||||||
|
"methods": [
|
||||||
|
{
|
||||||
|
"name": "<init>",
|
||||||
|
"parameterTypes": []
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "rubberbuf.ast_postprocess$eval242",
|
||||||
|
"methods": [
|
||||||
|
{
|
||||||
|
"name": "<init>",
|
||||||
|
"parameterTypes": []
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "rubberbuf.ast_postprocess$eval331",
|
||||||
|
"methods": [
|
||||||
|
{
|
||||||
|
"name": "<init>",
|
||||||
|
"parameterTypes": []
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "rubberbuf.ast_postprocess__init"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "rubberbuf.ast_preprocess$eval148",
|
||||||
|
"methods": [
|
||||||
|
{
|
||||||
|
"name": "<init>",
|
||||||
|
"parameterTypes": []
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "rubberbuf.ast_preprocess$eval15",
|
||||||
|
"methods": [
|
||||||
|
{
|
||||||
|
"name": "<init>",
|
||||||
|
"parameterTypes": []
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "rubberbuf.ast_preprocess$eval179",
|
||||||
|
"methods": [
|
||||||
|
{
|
||||||
|
"name": "<init>",
|
||||||
|
"parameterTypes": []
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "rubberbuf.ast_preprocess$eval254",
|
||||||
|
"methods": [
|
||||||
|
{
|
||||||
|
"name": "<init>",
|
||||||
|
"parameterTypes": []
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "rubberbuf.ast_preprocess$eval265",
|
||||||
|
"methods": [
|
||||||
|
{
|
||||||
|
"name": "<init>",
|
||||||
|
"parameterTypes": []
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "rubberbuf.ast_preprocess$eval279",
|
||||||
|
"methods": [
|
||||||
|
{
|
||||||
|
"name": "<init>",
|
||||||
|
"parameterTypes": []
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "rubberbuf.ast_preprocess$eval290",
|
||||||
|
"methods": [
|
||||||
|
{
|
||||||
|
"name": "<init>",
|
||||||
|
"parameterTypes": []
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "rubberbuf.ast_preprocess$eval301",
|
||||||
|
"methods": [
|
||||||
|
{
|
||||||
|
"name": "<init>",
|
||||||
|
"parameterTypes": []
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "rubberbuf.ast_preprocess$eval314",
|
||||||
|
"methods": [
|
||||||
|
{
|
||||||
|
"name": "<init>",
|
||||||
|
"parameterTypes": []
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "rubberbuf.ast_preprocess$eval321",
|
||||||
|
"methods": [
|
||||||
|
{
|
||||||
|
"name": "<init>",
|
||||||
|
"parameterTypes": []
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "rubberbuf.ast_preprocess__init"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "rubberbuf.ast_util__init"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "rubberbuf.core__init"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "rubberbuf.ebnf__init"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "rubberbuf.parse__init"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "rubberbuf.parse_textformat__init"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "rubberbuf.util__init"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name":"clojobuf.constant__init"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name":"clojobuf.core__init"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name":"clojobuf.decode__init"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name":"clojobuf.encode__init"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name":"clojobuf.schema$eval367",
|
||||||
|
"methods":[{"name":"<init>","parameterTypes":[] }]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name":"clojobuf.schema$eval396",
|
||||||
|
"methods":[{"name":"<init>","parameterTypes":[] }]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name":"clojobuf.schema__init"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name":"clojobuf.util__init"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name":"clojobuf_codec.decode__init"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name":"clojobuf_codec.deserialize__init"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name":"clojobuf_codec.encode__init"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name":"clojobuf_codec.io.reader.ByteReader"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name":"clojobuf_codec.io.reader__init"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name":"clojobuf_codec.io.writer.ByteWriter"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name":"clojobuf_codec.io.writer__init"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name":"clojobuf_codec.serialize__init"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name":"clojobuf_codec.util__init"
|
||||||
|
}
|
||||||
|
]
|
||||||
Reference in New Issue
Block a user