@@ -5,12 +5,15 @@ import (
55 "testing"
66 "time"
77
8+ "github.com/deis/builder/pkg/controller"
9+
810 "github.com/Masterminds/cookoo"
911 "golang.org/x/crypto/ssh"
1012)
1113
1214const (
13- testingServerAddr = "127.0.0.1:2244"
15+ testingServerAddr = "127.0.0.1:2244"
16+ testingServerAddr2 = "127.0.0.1:2245"
1417)
1518
1619// TestServer tests the SSH server.
@@ -20,7 +23,7 @@ const (
2023// used here. It's not recommended that you try to start another SSH server on
2124// the same port (at a later time) or else you will have key issues that you
2225// must manually resolve.
23- func TestServer (t * testing.T ) {
26+ func TestReceive (t * testing.T ) {
2427 key , err := sshTestingHostKey ()
2528 if err != nil {
2629 t .Fatal (err )
@@ -32,7 +35,7 @@ func TestServer(t *testing.T) {
3235 cfg .AddHostKey (key )
3336
3437 c := NewCircuit ()
35- cxt := runServer (& cfg , c , t )
38+ cxt := runServer (& cfg , c , testingServerAddr , t )
3639
3740 // Give server time to initialize.
3841 time .Sleep (200 * time .Millisecond )
@@ -79,15 +82,79 @@ func TestServer(t *testing.T) {
7982 closer <- true
8083}
8184
85+ func TestPush (t * testing.T ) {
86+ key , err := sshTestingHostKey ()
87+ if err != nil {
88+ t .Fatal (err )
89+ }
90+
91+ cfg := ssh.ServerConfig {
92+ NoClientAuth : true ,
93+ }
94+ cfg .AddHostKey (key )
95+
96+ c := NewCircuit ()
97+ runServer (& cfg , c , testingServerAddr2 , t )
98+
99+ // Give server time to initialize.
100+ time .Sleep (200 * time .Millisecond )
101+
102+ if c .State () != ClosedState {
103+ t .Fatalf ("circuit was not in closed state" )
104+ }
105+
106+ // Connect to the server and issue env var set. This should return true.
107+ client , err := ssh .Dial ("tcp" , testingServerAddr2 , & ssh.ClientConfig {})
108+ if err != nil {
109+ t .Fatalf ("Failed to connect client to local server: %s" , err )
110+ }
111+ sess , err := client .NewSession ()
112+ if err != nil {
113+ t .Fatalf ("Failed to create client session: %s" , err )
114+ }
115+
116+ // check for invalid length of arguments
117+ if out , err := sess .Output ("git-upload-pack" ); err == nil {
118+ t .Errorf ("Expected an error but '%s' was received" , out )
119+ } else if string (out ) != "" {
120+ t .Errorf ("Expected , got '%s'" , out )
121+ }
122+ sess .Close ()
123+
124+ go func () {
125+ sess , err = client .NewSession ()
126+ if err != nil {
127+ t .Fatalf ("Failed to create client session: %s" , err )
128+ }
129+ if out , err := sess .Output ("git-upload-pack /demo.git" ); err != nil {
130+ t .Errorf ("Unexpected error %s, Output '%s'" , err , out )
131+ } else if string (out ) != "OK" {
132+ t .Errorf ("Expected 'OK' got '%s'" , out )
133+ }
134+ sess .Close ()
135+ }()
136+
137+ time .Sleep (2 * time .Second )
138+
139+ sess , err = client .NewSession ()
140+ if err != nil {
141+ t .Fatalf ("Failed to create client session: %s" , err )
142+ }
143+ if out , err := sess .Output ("git-upload-pack /demo.git" ); err == nil {
144+ t .Errorf ("Expected an error but returned without errors '%s'" , out )
145+ }
146+ sess .Close ()
147+ }
148+
82149// sshTestingHostKey loads the testing key.
83150func sshTestingHostKey () (ssh.Signer , error ) {
84151 return ssh .ParsePrivateKey ([]byte (testingHostKey ))
85152}
86153
87- func runServer (config * ssh.ServerConfig , c * Circuit , t * testing.T ) cookoo.Context {
154+ func runServer (config * ssh.ServerConfig , c * Circuit , testAddr string , t * testing.T ) cookoo.Context {
88155 reg , router , cxt := cookoo .Cookoo ()
89156 cxt .Put (ServerConfig , config )
90- cxt .Put (Address , testingServerAddr )
157+ cxt .Put (Address , testAddr )
91158 cxt .Put ("cookoo.Router" , router )
92159
93160 reg .AddRoute (cookoo.Route {
@@ -105,14 +172,72 @@ func runServer(config *ssh.ServerConfig, c *Circuit, t *testing.T) cookoo.Contex
105172 },
106173 })
107174
175+ reg .AddRoute (cookoo.Route {
176+ Name : "pubkeyAuth" ,
177+ Does : []cookoo.Task {
178+ cookoo.Cmd {
179+ Name : "authN" ,
180+ Fn : mockAuthKey ,
181+ Using : []cookoo.Param {
182+ {Name : "metadata" , From : "cxt:metadata" },
183+ {Name : "key" , From : "cxt:key" },
184+ {Name : "repoName" , From : "cxt:repository" },
185+ },
186+ },
187+ },
188+ })
189+
190+ reg .AddRoute (cookoo.Route {
191+ Name : "sshGitReceive" ,
192+ Does : []cookoo.Task {
193+ cookoo.Cmd {
194+ Name : "receive" ,
195+ Fn : mockDummyReceive ,
196+ Using : []cookoo.Param {
197+ {Name : "request" , From : "cxt:request" },
198+ {Name : "channel" , From : "cxt:channel" },
199+ {Name : "operation" , From : "cxt:operation" },
200+ {Name : "repoName" , From : "cxt:repository" },
201+ {Name : "permissions" , From : "cxt:authN" },
202+ {Name : "userinfo" , From : "cxt:userinfo" },
203+ },
204+ },
205+ },
206+ })
207+
108208 go func () {
109209 if err := Serve (reg , router , c , cxt ); err != nil {
110210 t .Fatalf ("Failed serving with %s" , err )
111211 }
112212 }()
113213
114214 return cxt
215+ }
216+
217+ func mockAuthKey (c cookoo.Context , p * cookoo.Params ) (interface {}, cookoo.Interrupt ) {
218+ c .Put ("userinfo" , & controller.UserInfo {
219+ Username : "deis" ,
220+ Key : testingClientPubKey ,
221+ Fingerprint : "" ,
222+ Apps : []string {"demo" },
223+ })
224+
225+ perm := & ssh.Permissions {
226+ Extensions : map [string ]string {
227+ "user" : "deis" ,
228+ },
229+ }
230+ return perm , nil
231+ }
115232
233+ func mockDummyReceive (c cookoo.Context , p * cookoo.Params ) (interface {}, cookoo.Interrupt ) {
234+ channel := p .Get ("channel" , nil ).(ssh.Channel )
235+ req := p .Get ("request" , nil ).(* ssh.Request )
236+ time .Sleep (5 * time .Second )
237+ channel .Write ([]byte ("OK" ))
238+ sendExitStatus (0 , channel )
239+ req .Reply (true , nil )
240+ return nil , nil
116241}
117242
118243// connMetadata mocks ssh.ConnMetadata for authentication.
0 commit comments