Last active
December 3, 2015 00:30
-
-
Save bartojs/bc6b503a0847e46359a4 to your computer and use it in GitHub Desktop.
sftp with publickey using apache-sshd
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
;; 1) download this build.boot file | |
;; 2) download & install http://boot-clj.com | |
;; 3) cp ~/.ssh/id_rsa.pub authorized_keys | |
;; 4) boot run | |
;; -- this will run the server for a minute on port 2222 | |
;; 5) test with scp -v -i ~/.ssh/id_rsa -P 2222 mytestfile-original.txt localhost:mytestfile-transferred.txt | |
;; 6) check scp output for which keys are sent - remember to check if ssh-agent is running (which will cache keys) | |
(set-env! :dependencies '[[org.apache.sshd/sshd-core "0.9.0"] | |
[org.apache.sshd/sshd-sftp "0.9.0"]]) | |
(require '[clojure.java.io :as io]) | |
(import org.apache.sshd.SshServer | |
org.apache.sshd.sftp.subsystem.SftpSubsystem$Factory | |
org.apache.sshd.server.command.ScpCommandFactory | |
org.apache.sshd.server.auth.UserAuthPublicKey$Factory | |
org.apache.sshd.server.PublickeyAuthenticator | |
org.apache.sshd.server.keyprovider.SimpleGeneratorHostKeyProvider | |
org.apache.mina.util.Base64 | |
java.nio.ByteBuffer | |
[java.security KeyFactory PublicKey] | |
[java.security.interfaces RSAPublicKey DSAPublicKey] | |
[java.security.spec DSAPublicKeySpec RSAPublicKeySpec]) | |
(defn readbytes [buf] | |
(let [bytearray (byte-array (.getInt buf))] | |
(.get buf bytearray) | |
bytearray)) | |
(defn readbigint [buf] | |
(-> buf (readbytes) (BigInteger.))) | |
(defn linebuf [line] | |
(let [buf (-> line (.split " ") (first) (.getBytes) (Base64/decodeBase64) (ByteBuffer/wrap))] | |
(readbytes buf) | |
buf)) | |
(defn parse-rsa [line] | |
(let [buf (linebuf line) | |
exp (readbigint buf) | |
mod (readbigint buf)] | |
(.generatePublic (KeyFactory/getInstance "RSA") (RSAPublicKeySpec. mod exp)))) | |
(defn parse-dsa [line] | |
(let [buf (linebuf line) | |
p (readbigint buf) | |
q (readbigint buf) | |
g (readbigint buf) | |
y (readbigint buf)] | |
(.generatePublic (KeyFactory/getInstance "DSA") (DSAPublicKeySpec. y p q g)))) | |
(defn parse-key [line] | |
(let [l (.trim line)] | |
(println "authorized key " l) | |
(cond (.startsWith l "ssh-rsa ") (parse-rsa (subs l 8)) | |
(.startsWith l "ssh-dsa ") (parse-dsa (subs l 8)) | |
(.startsWith l "ssh-dss ") (parse-dsa (subs l 8)) | |
:else nil))) | |
(defn samekey? [k1 k2] | |
(or (and | |
(instance? RSAPublicKey k1) | |
(instance? RSAPublicKey k2) | |
(= (.getModulus k1) (.getModulus k2)) | |
(= (.getPublicExponent k1) (.getPublicExponent k2))) | |
(and | |
(instance? DSAPublicKey k1) | |
(instance? DSAPublicKey k2) | |
(= (.getY k1) (.getY k2)) | |
(= (.getP (.getParams k1)) (.getP (.getParams k2))) | |
(= (.getQ (.getParams k1)) (.getQ (.getParams k2))) | |
(= (.getG (.getParams k1)) (.getG (.getParams k2)))))) | |
(defn auth [user pk] | |
(let [ks (keep parse-key (line-seq (io/reader "authorized_keys")))] | |
(some (partial samekey? pk) ks))) | |
(def sshd (doto (SshServer/setUpDefaultServer) | |
(.setPort 2222) | |
(.setKeyPairProvider (SimpleGeneratorHostKeyProvider. "sshd.ser")) | |
(.setSubsystemFactories [(SftpSubsystem$Factory.)]) | |
(.setCommandFactory (ScpCommandFactory.)) | |
(.setUserAuthFactories [(UserAuthPublicKey$Factory.)]) | |
(.setPublickeyAuthenticator (reify PublickeyAuthenticator (authenticate [this user publickey session] (auth user publickey)))))) | |
(deftask run [] | |
(.start sshd) | |
(Thread/sleep 60000)) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment