a geicko-2 based round robin ranking system designed to test c++ battleship submissions battleship.dunkirk.sh
1package ssh 2 3import ( 4 "context" 5 "encoding/hex" 6 "net" 7 "sync" 8 9 gossh "golang.org/x/crypto/ssh" 10) 11 12// contextKey is a value for use with context.WithValue. It's used as 13// a pointer so it fits in an interface{} without allocation. 14type contextKey struct { 15 name string 16} 17 18var ( 19 // ContextKeyUser is a context key for use with Contexts in this package. 20 // The associated value will be of type string. 21 ContextKeyUser = &contextKey{"user"} 22 23 // ContextKeySessionID is a context key for use with Contexts in this package. 24 // The associated value will be of type string. 25 ContextKeySessionID = &contextKey{"session-id"} 26 27 // ContextKeyPermissions is a context key for use with Contexts in this package. 28 // The associated value will be of type *Permissions. 29 ContextKeyPermissions = &contextKey{"permissions"} 30 31 // ContextKeyClientVersion is a context key for use with Contexts in this package. 32 // The associated value will be of type string. 33 ContextKeyClientVersion = &contextKey{"client-version"} 34 35 // ContextKeyServerVersion is a context key for use with Contexts in this package. 36 // The associated value will be of type string. 37 ContextKeyServerVersion = &contextKey{"server-version"} 38 39 // ContextKeyLocalAddr is a context key for use with Contexts in this package. 40 // The associated value will be of type net.Addr. 41 ContextKeyLocalAddr = &contextKey{"local-addr"} 42 43 // ContextKeyRemoteAddr is a context key for use with Contexts in this package. 44 // The associated value will be of type net.Addr. 45 ContextKeyRemoteAddr = &contextKey{"remote-addr"} 46 47 // ContextKeyServer is a context key for use with Contexts in this package. 48 // The associated value will be of type *Server. 49 ContextKeyServer = &contextKey{"ssh-server"} 50 51 // ContextKeyConn is a context key for use with Contexts in this package. 52 // The associated value will be of type gossh.ServerConn. 53 ContextKeyConn = &contextKey{"ssh-conn"} 54 55 // ContextKeyPublicKey is a context key for use with Contexts in this package. 56 // The associated value will be of type PublicKey. 57 ContextKeyPublicKey = &contextKey{"public-key"} 58 59 // ContextKeySession is a context key for use with Contexts in this package. 60 // The associated value will be of type Session. 61 ContextKeySession = &contextKey{"session"} 62) 63 64// Context is a package specific context interface. It exposes connection 65// metadata and allows new values to be easily written to it. It's used in 66// authentication handlers and callbacks, and its underlying context.Context is 67// exposed on Session in the session Handler. A connection-scoped lock is also 68// embedded in the context to make it easier to limit operations per-connection. 69type Context interface { 70 context.Context 71 sync.Locker 72 73 // User returns the username used when establishing the SSH connection. 74 User() string 75 76 // SessionID returns the session hash. 77 SessionID() string 78 79 // ClientVersion returns the version reported by the client. 80 ClientVersion() string 81 82 // ServerVersion returns the version reported by the server. 83 ServerVersion() string 84 85 // RemoteAddr returns the remote address for this connection. 86 RemoteAddr() net.Addr 87 88 // LocalAddr returns the local address for this connection. 89 LocalAddr() net.Addr 90 91 // Permissions returns the Permissions object used for this connection. 92 Permissions() *Permissions 93 94 // SetValue allows you to easily write new values into the underlying context. 95 SetValue(key, value interface{}) 96} 97 98type sshContext struct { 99 context.Context 100 *sync.Mutex 101 102 values map[interface{}]interface{} 103 valuesMu sync.Mutex 104} 105 106var _ context.Context = &sshContext{} 107 108var _ sync.Locker = &sshContext{} 109 110func newContext(srv *Server) (*sshContext, context.CancelFunc) { 111 innerCtx, cancel := context.WithCancel(context.Background()) 112 ctx := &sshContext{ 113 Context: innerCtx, 114 Mutex: &sync.Mutex{}, 115 values: make(map[interface{}]interface{}), 116 } 117 ctx.SetValue(ContextKeyServer, srv) 118 perms := &Permissions{&gossh.Permissions{}} 119 ctx.SetValue(ContextKeyPermissions, perms) 120 return ctx, cancel 121} 122 123func resetPermissions(ctx Context) { 124 ctx.Permissions().Permissions = &gossh.Permissions{} 125} 126 127// this is separate from newContext because we will get ConnMetadata 128// at different points so it needs to be applied separately 129func applyConnMetadata(ctx Context, conn gossh.ConnMetadata) { 130 if ctx.Value(ContextKeySessionID) != nil { 131 return 132 } 133 ctx.SetValue(ContextKeySessionID, hex.EncodeToString(conn.SessionID())) 134 ctx.SetValue(ContextKeyClientVersion, string(conn.ClientVersion())) 135 ctx.SetValue(ContextKeyServerVersion, string(conn.ServerVersion())) 136 ctx.SetValue(ContextKeyUser, conn.User()) 137 ctx.SetValue(ContextKeyLocalAddr, conn.LocalAddr()) 138 ctx.SetValue(ContextKeyRemoteAddr, conn.RemoteAddr()) 139} 140 141func (ctx *sshContext) Value(key interface{}) interface{} { 142 ctx.valuesMu.Lock() 143 defer ctx.valuesMu.Unlock() 144 if v, ok := ctx.values[key]; ok { 145 return v 146 } 147 return ctx.Context.Value(key) 148} 149 150func (ctx *sshContext) SetValue(key, value interface{}) { 151 ctx.valuesMu.Lock() 152 defer ctx.valuesMu.Unlock() 153 ctx.values[key] = value 154} 155 156func (ctx *sshContext) User() string { 157 return ctx.Value(ContextKeyUser).(string) 158} 159 160func (ctx *sshContext) SessionID() string { 161 return ctx.Value(ContextKeySessionID).(string) 162} 163 164func (ctx *sshContext) ClientVersion() string { 165 return ctx.Value(ContextKeyClientVersion).(string) 166} 167 168func (ctx *sshContext) ServerVersion() string { 169 return ctx.Value(ContextKeyServerVersion).(string) 170} 171 172func (ctx *sshContext) RemoteAddr() net.Addr { 173 if addr, ok := ctx.Value(ContextKeyRemoteAddr).(net.Addr); ok { 174 return addr 175 } 176 return nil 177} 178 179func (ctx *sshContext) LocalAddr() net.Addr { 180 return ctx.Value(ContextKeyLocalAddr).(net.Addr) 181} 182 183func (ctx *sshContext) Permissions() *Permissions { 184 return ctx.Value(ContextKeyPermissions).(*Permissions) 185}