Skip to content

Commit 7189a41

Browse files
committed
Add user auth
1 parent 1eef7ee commit 7189a41

File tree

4 files changed

+60
-16
lines changed

4 files changed

+60
-16
lines changed

ssh/README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ To generate TLS connection certificates:
2121
# Client
2222
cd ~/.ssh
2323
openssl req -newkey rsa:2048 -nodes -keyout quic-conn-key.pem -x509 -days 365 -out quic-conn-certificate.pem
24-
# Server
24+
-# Server
2525
cd /etc/ssh
2626
sudo openssl req -newkey rsa:2048 -nodes -keyout quic-conn-key.pem -x509 -days 365 -out quic-conn-certificate.pem
2727
```
@@ -50,7 +50,7 @@ sudo -E ./server -oPort=2200 -oAuthorizedKeysFile=./authorized_keys
5050
Running the client:
5151
```
5252
cd $GOPATH/src/github.com/netsec-ethz/scion-apps/ssh/client
53-
./client -p 2200 1-11,[127.0.0.1]
53+
./client -p 2200 1-11,[127.0.0.1] -oUser=username
5454
```
5555

5656
Using SCP (make sure you've done `chmod +x ./scp.sh` first):

ssh/client/clientconfig/clientconfig.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ type ClientConfig struct {
2020
// Create creates a new ClientConfig with the default values.
2121
func Create() *ClientConfig {
2222
return &ClientConfig{
23+
User: "",
2324
HostAddress: "",
2425
Port: "22",
2526
PasswordAuthentication: "yes",

ssh/server/ssh/authcallbacks.go

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,11 @@ func (s *Server) PasswordAuth(c ssh.ConnMetadata, pass []byte) (*ssh.Permissions
2626
return nil, fmt.Errorf("Authenticate: %s", err.Error())
2727
}
2828

29-
return nil, nil
29+
return &ssh.Permissions{
30+
CriticalOptions: map[string]string{
31+
"user": c.User(),
32+
},
33+
}, nil
3034
}
3135

3236
func loadAuthorizedKeys(file string) (map[string]bool, error) {
@@ -59,8 +63,11 @@ func (s *Server) PublicKeyAuth(c ssh.ConnMetadata, pubKey ssh.PublicKey) (*ssh.P
5963

6064
if authKeys[string(pubKey.Marshal())] {
6165
return &ssh.Permissions{
62-
// Record the public key used for authentication.
66+
CriticalOptions: map[string]string{
67+
"user": c.User(),
68+
},
6369
Extensions: map[string]string{
70+
// Record the public key used for authentication
6471
"pubkey-fp": ssh.FingerprintSHA256(pubKey),
6572
},
6673
}, nil

ssh/server/ssh/sessionchannel.go

Lines changed: 48 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@ import (
55
"io"
66
"os"
77
"os/exec"
8+
"os/user"
9+
"strconv"
810
"sync"
911
"syscall"
1012
"unsafe"
@@ -39,6 +41,35 @@ func handleSession(perms *ssh.Permissions, newChannel ssh.NewChannel) {
3941

4042
execCmd := func(name string, arg ...string) error {
4143
cmd := exec.Command(name, arg...)
44+
username, ok := perms.CriticalOptions["user"]
45+
var usr *user.User
46+
if ok {
47+
var err error
48+
usr, err = user.Lookup(username)
49+
if err != nil {
50+
return err
51+
}
52+
} else {
53+
usr, err = user.Current()
54+
if err != nil {
55+
return err
56+
}
57+
}
58+
uid, err := strconv.ParseUint(usr.Uid, 10, 32)
59+
if err != nil {
60+
return err
61+
}
62+
gid, err := strconv.ParseUint(usr.Gid, 10, 32)
63+
if err != nil {
64+
return err
65+
}
66+
if cmd.SysProcAttr == nil {
67+
cmd.SysProcAttr = &syscall.SysProcAttr{}
68+
}
69+
cmd.SysProcAttr.Credential = &syscall.Credential{
70+
Uid: uint32(uid),
71+
Gid: uint32(gid),
72+
}
4273
close := func() {
4374
cmd.Process.Kill()
4475
err := cmd.Wait()
@@ -47,20 +78,16 @@ func handleSession(perms *ssh.Permissions, newChannel ssh.NewChannel) {
4778
}
4879

4980
tb := []byte{0, 0, 0, 0}
50-
connection.SendRequest("exit-status", false, tb)
81+
_, err = connection.SendRequest("exit-status", false, tb)
82+
if err != nil {
83+
log.Error("Error sending exit status", "error", err)
84+
}
5185

5286
once.Do(closeConn)
5387

5488
log.Debug("Session closed")
5589
}
5690

57-
var pipesWait sync.WaitGroup
58-
pipesWait.Add(2)
59-
go func() {
60-
pipesWait.Wait()
61-
close()
62-
}()
63-
6491
if hasRequestedPty {
6592
log.Debug("Creating pty...")
6693
cmdf, err = pty.Start(cmd)
@@ -70,12 +97,14 @@ func handleSession(perms *ssh.Permissions, newChannel ssh.NewChannel) {
7097

7198
var once sync.Once
7299
go func() {
73-
io.Copy(connection, cmdf)
74-
pipesWait.Done()
100+
_, err := io.Copy(connection, cmdf)
101+
log.Debug("Pty to connection copy ended", "error", err)
102+
once.Do(close)
75103
}()
76104
go func() {
77-
io.Copy(cmdf, connection)
78-
pipesWait.Done()
105+
_, err := io.Copy(cmdf, connection)
106+
log.Debug("Connection to pty copy ended", "error", err)
107+
once.Do(close)
79108
}()
80109

81110
termLen := ptyPayload[3]
@@ -98,6 +127,13 @@ func handleSession(perms *ssh.Permissions, newChannel ssh.NewChannel) {
98127
}
99128

100129
// we want to wait for stdout and stderr before closing connection, but don't really mind about stdin
130+
var pipesWait sync.WaitGroup
131+
pipesWait.Add(2)
132+
go func() {
133+
pipesWait.Wait()
134+
close()
135+
}()
136+
101137
go func() {
102138
_, err := io.Copy(stdin, connection)
103139
log.Debug("Stdin copy ended", "error", err)

0 commit comments

Comments
 (0)