github.com/amitbet/vnc2video@v0.0.0-20190616012314-9d50b9dab1d9/handlers.go (about) 1 package vnc2video 2 3 import ( 4 "encoding/binary" 5 "fmt" 6 "github.com/amitbet/vnc2video/logger" 7 ) 8 9 // Handler represents handler of handshake 10 type Handler interface { 11 Handle(Conn) error 12 } 13 14 // ProtoVersionLength protocol version length 15 const ProtoVersionLength = 12 16 17 const ( 18 // ProtoVersionUnknown unknown version 19 ProtoVersionUnknown = "" 20 // ProtoVersion33 sets if proto 003.003 21 ProtoVersion33 = "RFB 003.003\n" 22 // ProtoVersion38 sets if proto 003.008 23 ProtoVersion38 = "RFB 003.008\n" 24 // ProtoVersion37 sets if proto 003.007 25 ProtoVersion37 = "RFB 003.007\n" 26 ) 27 28 // ParseProtoVersion parse protocol version 29 func ParseProtoVersion(pv []byte) (uint, uint, error) { 30 var major, minor uint 31 32 if len(pv) < ProtoVersionLength { 33 return 0, 0, fmt.Errorf("ProtocolVersion message too short (%v < %v)", len(pv), ProtoVersionLength) 34 } 35 36 l, err := fmt.Sscanf(string(pv), "RFB %d.%d\n", &major, &minor) 37 if l != 2 { 38 return 0, 0, fmt.Errorf("error parsing protocol version") 39 } 40 if err != nil { 41 return 0, 0, err 42 } 43 44 return major, minor, nil 45 } 46 47 // DefaultClientVersionHandler represents default handler 48 type DefaultClientVersionHandler struct{} 49 50 // Handle provide version handler for client side 51 func (*DefaultClientVersionHandler) Handle(c Conn) error { 52 var version [ProtoVersionLength]byte 53 54 if err := binary.Read(c, binary.BigEndian, &version); err != nil { 55 return err 56 } 57 58 major, minor, err := ParseProtoVersion(version[:]) 59 if err != nil { 60 return err 61 } 62 63 pv := ProtoVersionUnknown 64 if major == 3 { 65 if minor >= 8 { 66 pv = ProtoVersion38 67 } else if minor >= 3 { 68 pv = ProtoVersion38 69 } 70 } 71 if pv == ProtoVersionUnknown { 72 return fmt.Errorf("ProtocolVersion handshake failed; unsupported version '%v'", string(version[:])) 73 } 74 c.SetProtoVersion(string(version[:])) 75 76 if err := binary.Write(c, binary.BigEndian, []byte(pv)); err != nil { 77 return err 78 } 79 return c.Flush() 80 } 81 82 // DefaultServerVersionHandler represents default server handler 83 type DefaultServerVersionHandler struct{} 84 85 // Handle provide server version handler 86 func (*DefaultServerVersionHandler) Handle(c Conn) error { 87 var version [ProtoVersionLength]byte 88 if err := binary.Write(c, binary.BigEndian, []byte(ProtoVersion38)); err != nil { 89 return err 90 } 91 if err := c.Flush(); err != nil { 92 return err 93 } 94 if err := binary.Read(c, binary.BigEndian, &version); err != nil { 95 return err 96 } 97 major, minor, err := ParseProtoVersion(version[:]) 98 if err != nil { 99 return err 100 } 101 102 pv := ProtoVersionUnknown 103 if major == 3 { 104 if minor >= 8 { 105 pv = ProtoVersion38 106 } else if minor >= 3 { 107 pv = ProtoVersion33 108 } 109 } 110 if pv == ProtoVersionUnknown { 111 return fmt.Errorf("ProtocolVersion handshake failed; unsupported version '%v'", string(version[:])) 112 } 113 114 c.SetProtoVersion(pv) 115 return nil 116 } 117 118 // DefaultClientSecurityHandler used for client security handler 119 type DefaultClientSecurityHandler struct{} 120 121 // Handle provide client side security handler 122 func (*DefaultClientSecurityHandler) Handle(c Conn) error { 123 cfg := c.Config().(*ClientConfig) 124 var numSecurityTypes uint8 125 if err := binary.Read(c, binary.BigEndian, &numSecurityTypes); err != nil { 126 return err 127 } 128 secTypes := make([]SecurityType, numSecurityTypes) 129 if err := binary.Read(c, binary.BigEndian, &secTypes); err != nil { 130 return err 131 } 132 133 var secType SecurityHandler 134 for _, st := range cfg.SecurityHandlers { 135 for _, sc := range secTypes { 136 if st.Type() == sc { 137 secType = st 138 } 139 } 140 } 141 142 if err := binary.Write(c, binary.BigEndian, cfg.SecurityHandlers[0].Type()); err != nil { 143 return err 144 } 145 146 if err := c.Flush(); err != nil { 147 return err 148 } 149 150 err := secType.Auth(c) 151 if err != nil { 152 logger.Error("Authentication error: ", err) 153 return err 154 } 155 156 var authCode uint32 157 if err := binary.Read(c, binary.BigEndian, &authCode); err != nil { 158 return err 159 } 160 161 logger.Tracef("authenticating, secType: %d, auth code(0=success): %d", secType.Type(), authCode) 162 if authCode == 1 { 163 var reasonLength uint32 164 if err := binary.Read(c, binary.BigEndian, &reasonLength); err != nil { 165 return err 166 } 167 reasonText := make([]byte, reasonLength) 168 if err := binary.Read(c, binary.BigEndian, &reasonText); err != nil { 169 return err 170 } 171 return fmt.Errorf("%s", reasonText) 172 } 173 c.SetSecurityHandler(secType) 174 return nil 175 } 176 177 // DefaultServerSecurityHandler used for server security handler 178 type DefaultServerSecurityHandler struct{} 179 180 // Handle provide server side security handler 181 func (*DefaultServerSecurityHandler) Handle(c Conn) error { 182 cfg := c.Config().(*ServerConfig) 183 var secType SecurityType 184 if c.Protocol() == ProtoVersion37 || c.Protocol() == ProtoVersion38 { 185 if err := binary.Write(c, binary.BigEndian, uint8(len(cfg.SecurityHandlers))); err != nil { 186 return err 187 } 188 189 for _, sectype := range cfg.SecurityHandlers { 190 if err := binary.Write(c, binary.BigEndian, sectype.Type()); err != nil { 191 return err 192 } 193 } 194 } else { 195 st := uint32(0) 196 for _, sectype := range cfg.SecurityHandlers { 197 if uint32(sectype.Type()) > st { 198 st = uint32(sectype.Type()) 199 secType = sectype.Type() 200 } 201 } 202 if err := binary.Write(c, binary.BigEndian, st); err != nil { 203 return err 204 } 205 } 206 if err := c.Flush(); err != nil { 207 return err 208 } 209 210 if c.Protocol() == ProtoVersion38 { 211 if err := binary.Read(c, binary.BigEndian, &secType); err != nil { 212 return err 213 } 214 } 215 secTypes := make(map[SecurityType]SecurityHandler) 216 for _, sType := range cfg.SecurityHandlers { 217 secTypes[sType.Type()] = sType 218 } 219 220 sType, ok := secTypes[secType] 221 if !ok { 222 return fmt.Errorf("security type %d not implemented", secType) 223 } 224 225 var authCode uint32 226 authErr := sType.Auth(c) 227 if authErr != nil { 228 authCode = uint32(1) 229 } 230 231 if err := binary.Write(c, binary.BigEndian, authCode); err != nil { 232 return err 233 } 234 235 if authErr == nil { 236 if err := c.Flush(); err != nil { 237 return err 238 } 239 c.SetSecurityHandler(sType) 240 return nil 241 } 242 243 if c.Protocol() == ProtoVersion38 { 244 if err := binary.Write(c, binary.BigEndian, uint32(len(authErr.Error()))); err != nil { 245 return err 246 } 247 if err := binary.Write(c, binary.BigEndian, []byte(authErr.Error())); err != nil { 248 return err 249 } 250 if err := c.Flush(); err != nil { 251 return err 252 } 253 } 254 return authErr 255 } 256 257 // DefaultClientServerInitHandler default client server init handler 258 type DefaultClientServerInitHandler struct{} 259 260 // Handle provide default server init handler 261 func (*DefaultClientServerInitHandler) Handle(c Conn) error { 262 logger.Trace("starting DefaultClientServerInitHandler") 263 var err error 264 srvInit := ServerInit{} 265 266 if err = binary.Read(c, binary.BigEndian, &srvInit.FBWidth); err != nil { 267 return err 268 } 269 if err = binary.Read(c, binary.BigEndian, &srvInit.FBHeight); err != nil { 270 return err 271 } 272 if err = binary.Read(c, binary.BigEndian, &srvInit.PixelFormat); err != nil { 273 return err 274 } 275 if err = binary.Read(c, binary.BigEndian, &srvInit.NameLength); err != nil { 276 return err 277 } 278 279 srvInit.NameText = make([]byte, srvInit.NameLength) 280 if err = binary.Read(c, binary.BigEndian, &srvInit.NameText); err != nil { 281 return err 282 } 283 logger.Tracef("DefaultClientServerInitHandler got serverInit: %v", srvInit) 284 c.SetDesktopName(srvInit.NameText) 285 if c.Protocol() == "aten1" { 286 c.SetWidth(800) 287 c.SetHeight(600) 288 c.SetPixelFormat(NewPixelFormatAten()) 289 } else { 290 c.SetWidth(srvInit.FBWidth) 291 c.SetHeight(srvInit.FBHeight) 292 293 //telling the server to use 32bit pixels (with 24 dept, tight standard format) 294 pixelMsg := SetPixelFormat{PF: PixelFormat32bit} 295 pixelMsg.Write(c) 296 c.SetPixelFormat(PixelFormat32bit) 297 //c.SetPixelFormat(srvInit.PixelFormat) 298 } 299 if c.Protocol() == "aten1" { 300 ikvm := struct { 301 _ [8]byte 302 IKVMVideoEnable uint8 303 IKVMKMEnable uint8 304 IKVMKickEnable uint8 305 VUSBEnable uint8 306 }{} 307 if err = binary.Read(c, binary.BigEndian, &ikvm); err != nil { 308 return err 309 } 310 } 311 /* 312 caps := struct { 313 ServerMessagesNum uint16 314 ClientMessagesNum uint16 315 EncodingsNum uint16 316 _ [2]byte 317 }{} 318 if err := binary.Read(c, binary.BigEndian, &caps); err != nil { 319 return err 320 } 321 322 caps.ServerMessagesNum = uint16(1) 323 var item [16]byte 324 for i := uint16(0); i < caps.ServerMessagesNum; i++ { 325 if err := binary.Read(c, binary.BigEndian, &item); err != nil { 326 return err 327 } 328 fmt.Printf("server message cap %s\n", item) 329 } 330 331 for i := uint16(0); i < caps.ClientMessagesNum; i++ { 332 if err := binary.Read(c, binary.BigEndian, &item); err != nil { 333 return err 334 } 335 fmt.Printf("client message cap %s\n", item) 336 } 337 for i := uint16(0); i < caps.EncodingsNum; i++ { 338 if err := binary.Read(c, binary.BigEndian, &item); err != nil { 339 return err 340 } 341 fmt.Printf("encoding cap %s\n", item) 342 } 343 // var pad [1]byte 344 // if err := binary.Read(c, binary.BigEndian, &pad); err != nil { 345 // return err 346 // } 347 }*/ 348 return nil 349 } 350 351 // DefaultServerServerInitHandler default server server init handler 352 type DefaultServerServerInitHandler struct{} 353 354 // Handle provide default server server init handler 355 func (*DefaultServerServerInitHandler) Handle(c Conn) error { 356 if err := binary.Write(c, binary.BigEndian, c.Width()); err != nil { 357 return err 358 } 359 if err := binary.Write(c, binary.BigEndian, c.Height()); err != nil { 360 return err 361 } 362 if err := binary.Write(c, binary.BigEndian, c.PixelFormat()); err != nil { 363 return err 364 } 365 if err := binary.Write(c, binary.BigEndian, uint32(len(c.DesktopName()))); err != nil { 366 return err 367 } 368 if err := binary.Write(c, binary.BigEndian, []byte(c.DesktopName())); err != nil { 369 return err 370 } 371 return c.Flush() 372 } 373 374 // DefaultClientClientInitHandler default client client init handler 375 type DefaultClientClientInitHandler struct{} 376 377 // Handle provide default client client init handler 378 func (*DefaultClientClientInitHandler) Handle(c Conn) error { 379 logger.Trace("starting DefaultClientClientInitHandler") 380 cfg := c.Config().(*ClientConfig) 381 var shared uint8 382 if cfg.Exclusive { 383 shared = 0 384 } else { 385 shared = 1 386 } 387 if err := binary.Write(c, binary.BigEndian, shared); err != nil { 388 return err 389 } 390 logger.Tracef("DefaultClientClientInitHandler sending: shared=%d", shared) 391 return c.Flush() 392 } 393 394 // DefaultServerClientInitHandler default server client init handler 395 type DefaultServerClientInitHandler struct{} 396 397 // Handle provide default server client init handler 398 func (*DefaultServerClientInitHandler) Handle(c Conn) error { 399 var shared uint8 400 if err := binary.Read(c, binary.BigEndian, &shared); err != nil { 401 return err 402 } 403 /* TODO 404 if shared != 1 { 405 c.SetShared(false) 406 } 407 */ 408 return nil 409 }