Skip to content

Commit f09f9c8

Browse files
committed
Add NewCredentialSSHKeyFromSigner (#706)
This change adds `NewCredentialSSHKeyFromSigner`, which allows idiomatic use of SSH keys from Go. This also lets us spin off an SSH server in the tests. (cherry picked from commit abf02bc)
1 parent aae7e1b commit f09f9c8

20 files changed

+433
-7
lines changed

.github/workflows/ci.yml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ jobs:
3434
GOPATH: /home/runner/work/git2go
3535
run: |
3636
git submodule update --init
37+
sudo apt-get install -y --no-install-recommends libssh2-1-dev
3738
make build-libgit2-static
3839
go get -tags static -t github.com/${{ github.repository }}/...
3940
go build -tags static github.com/${{ github.repository }}/...
@@ -62,6 +63,7 @@ jobs:
6263
- name: Build
6364
run: |
6465
git submodule update --init
66+
sudo apt-get install -y --no-install-recommends libssh2-1-dev
6567
make build-libgit2-static
6668
- name: Test
6769
run: make TEST_ARGS=-test.v test-static
@@ -84,6 +86,7 @@ jobs:
8486
- name: Build
8587
run: |
8688
git submodule update --init
89+
sudo apt-get install -y --no-install-recommends libssh2-1-dev
8790
make build-libgit2-dynamic
8891
- name: Test
8992
run: make TEST_ARGS=-test.v test-dynamic
@@ -106,6 +109,7 @@ jobs:
106109
- name: Build libgit2
107110
run: |
108111
git submodule update --init
112+
sudo apt-get install -y --no-install-recommends libssh2-1-dev
109113
sudo ./script/build-libgit2.sh --dynamic --system
110114
- name: Test
111115
run: make TEST_ARGS=-test.v test
@@ -128,6 +132,7 @@ jobs:
128132
- name: Build libgit2
129133
run: |
130134
git submodule update --init
135+
sudo apt-get install -y --no-install-recommends libssh2-1-dev
131136
sudo ./script/build-libgit2.sh --static --system
132137
- name: Test
133138
run: go test --count=1 --tags "static,system_libgit2" ./...

.travis.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ go:
88
- tip
99

1010
install:
11+
- sudo apt-get install -y --no-install-recommends libssh2-1-dev
1112
- make build-libgit2-static
1213
- go get --tags "static" ./...
1314

credentials.go

Lines changed: 66 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,16 @@ package git
22

33
/*
44
#include <git2.h>
5+
6+
void _go_git_populate_credential_ssh_custom(git_cred_ssh_custom *cred);
57
*/
68
import "C"
7-
import "unsafe"
9+
import (
10+
"crypto/rand"
11+
"unsafe"
12+
13+
"golang.org/x/crypto/ssh"
14+
)
815

916
type CredType uint
1017

@@ -89,3 +96,61 @@ func NewCredDefault() (int, Cred) {
8996
ret := C.git_cred_default_new(&cred.ptr)
9097
return int(ret), cred
9198
}
99+
100+
type credentialSSHCustomData struct {
101+
signer ssh.Signer
102+
}
103+
104+
//export credentialSSHCustomFree
105+
func credentialSSHCustomFree(cred *C.git_cred_ssh_custom) {
106+
if cred == nil {
107+
return
108+
}
109+
110+
C.free(unsafe.Pointer(cred.username))
111+
C.free(unsafe.Pointer(cred.publickey))
112+
pointerHandles.Untrack(cred.payload)
113+
C.free(unsafe.Pointer(cred))
114+
}
115+
116+
//export credentialSSHSignCallback
117+
func credentialSSHSignCallback(
118+
errorMessage **C.char,
119+
sig **C.uchar,
120+
sig_len *C.size_t,
121+
data *C.uchar,
122+
data_len C.size_t,
123+
handle unsafe.Pointer,
124+
) C.int {
125+
signer := pointerHandles.Get(handle).(*credentialSSHCustomData).signer
126+
signature, err := signer.Sign(rand.Reader, C.GoBytes(unsafe.Pointer(data), C.int(data_len)))
127+
if err != nil {
128+
return setCallbackError(errorMessage, err)
129+
}
130+
*sig = (*C.uchar)(C.CBytes(signature.Blob))
131+
*sig_len = C.size_t(len(signature.Blob))
132+
return C.int(ErrorCodeOK)
133+
}
134+
135+
// NewCredentialSSHKeyFromSigner creates new SSH credentials using the provided signer.
136+
func NewCredentialSSHKeyFromSigner(username string, signer ssh.Signer) (*Cred, error) {
137+
publicKey := signer.PublicKey().Marshal()
138+
139+
ccred := (*C.git_cred_ssh_custom)(C.calloc(1, C.size_t(unsafe.Sizeof(C.git_cred_ssh_custom{}))))
140+
ccred.parent.credtype = C.GIT_CREDTYPE_SSH_CUSTOM
141+
ccred.username = C.CString(username)
142+
ccred.publickey = (*C.char)(C.CBytes(publicKey))
143+
ccred.publickey_len = C.size_t(len(publicKey))
144+
C._go_git_populate_credential_ssh_custom(ccred)
145+
146+
data := credentialSSHCustomData{
147+
signer: signer,
148+
}
149+
ccred.payload = pointerHandles.Track(&data)
150+
151+
cred := Cred{
152+
ptr: &ccred.parent,
153+
}
154+
155+
return &cred, nil
156+
}

go.mod

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,9 @@
11
module github.com/libgit2/git2go/v28
22

33
go 1.13
4+
5+
require (
6+
github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510
7+
golang.org/x/crypto v0.0.0-20201203163018-be400aefbc4c
8+
golang.org/x/sys v0.0.0-20201204225414-ed752295db88 // indirect
9+
)

go.sum

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 h1:El6M4kTTCOh6aBiKaUGG7oYTSPP8MxqL4YI3kZKwcP4=
2+
github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510/go.mod h1:pupxD2MaaD3pAXIBCelhxNneeOaAeabZDe5s4K6zSpQ=
3+
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
4+
golang.org/x/crypto v0.0.0-20201203163018-be400aefbc4c h1:9HhBz5L/UjnK9XLtiZhYAdue5BVKep3PMmS2LuPDt8k=
5+
golang.org/x/crypto v0.0.0-20201203163018-be400aefbc4c/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I=
6+
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
7+
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
8+
golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
9+
golang.org/x/sys v0.0.0-20201204225414-ed752295db88 h1:KmZPnMocC93w341XZp26yTJg8Za7lhb2KhkYmixoeso=
10+
golang.org/x/sys v0.0.0-20201204225414-ed752295db88/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
11+
golang.org/x/term v0.0.0-20201117132131-f5c789dd3221 h1:/ZHdbVpdR/jk3g30/d4yUL0JU9kksj8+F/bnQUVLGDM=
12+
golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw=
13+
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=

0 commit comments

Comments
 (0)