proto.c 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294
  1. #include "vnc.h"
  2. #define SHORT(p) (((p)[0]<<8)|((p)[1]))
  3. #define LONG(p) ((SHORT(p)<<16)|SHORT(p+2))
  4. uchar zero[64];
  5. Vnc*
  6. vncinit(int fd, int cfd, Vnc *v)
  7. {
  8. if(v == nil)
  9. v = mallocz(sizeof(*v), 1);
  10. Binit(&v->in, fd, OREAD);
  11. Binit(&v->out, fd, OWRITE);
  12. v->datafd = fd;
  13. v->ctlfd = cfd;
  14. return v;
  15. }
  16. void
  17. vncterm(Vnc *v)
  18. {
  19. Bterm(&v->out);
  20. Bterm(&v->in);
  21. }
  22. void
  23. vncflush(Vnc *v)
  24. {
  25. if(Bflush(&v->out) < 0){
  26. if(verbose > 1)
  27. fprint(2, "hungup while sending flush: %r\n");
  28. vnchungup(v);
  29. }
  30. }
  31. uchar
  32. vncrdchar(Vnc *v)
  33. {
  34. uchar buf[1];
  35. vncrdbytes(v, buf, 1);
  36. return buf[0];
  37. }
  38. ushort
  39. vncrdshort(Vnc *v)
  40. {
  41. uchar buf[2];
  42. vncrdbytes(v, buf, 2);
  43. return SHORT(buf);
  44. }
  45. ulong
  46. vncrdlong(Vnc *v)
  47. {
  48. uchar buf[4];
  49. vncrdbytes(v, buf, 4);
  50. return LONG(buf);
  51. }
  52. Point
  53. vncrdpoint(Vnc *v)
  54. {
  55. Point p;
  56. p.x = vncrdshort(v);
  57. p.y = vncrdshort(v);
  58. return p;
  59. }
  60. Rectangle
  61. vncrdrect(Vnc *v)
  62. {
  63. Rectangle r;
  64. r.min.x = vncrdshort(v);
  65. r.min.y = vncrdshort(v);
  66. r.max.x = r.min.x + vncrdshort(v);
  67. r.max.y = r.min.y + vncrdshort(v);
  68. return r;
  69. }
  70. Rectangle
  71. vncrdcorect(Vnc *v)
  72. {
  73. Rectangle r;
  74. r.min.x = vncrdchar(v);
  75. r.min.y = vncrdchar(v);
  76. r.max.x = r.min.x + vncrdchar(v);
  77. r.max.y = r.min.y + vncrdchar(v);
  78. return r;
  79. }
  80. void
  81. vncrdbytes(Vnc *v, void *a, int n)
  82. {
  83. if(Bread(&v->in, a, n) != n){
  84. if(verbose > 1)
  85. fprint(2, "hungup while reading\n");
  86. vnchungup(v);
  87. }
  88. }
  89. Pixfmt
  90. vncrdpixfmt(Vnc *v)
  91. {
  92. Pixfmt fmt;
  93. uchar pad[3];
  94. fmt.bpp = vncrdchar(v);
  95. fmt.depth = vncrdchar(v);
  96. fmt.bigendian = vncrdchar(v);
  97. fmt.truecolor = vncrdchar(v);
  98. fmt.red.max = vncrdshort(v);
  99. fmt.green.max = vncrdshort(v);
  100. fmt.blue.max = vncrdshort(v);
  101. fmt.red.shift = vncrdchar(v);
  102. fmt.green.shift = vncrdchar(v);
  103. fmt.blue.shift = vncrdchar(v);
  104. vncrdbytes(v, pad, 3);
  105. return fmt;
  106. }
  107. char*
  108. vncrdstring(Vnc *v)
  109. {
  110. ulong len;
  111. char *s;
  112. len = vncrdlong(v);
  113. s = malloc(len+1);
  114. assert(s != nil);
  115. vncrdbytes(v, s, len);
  116. s[len] = '\0';
  117. return s;
  118. }
  119. /*
  120. * on the server side of the negotiation protocol, we read
  121. * the client response and then run the negotiated function.
  122. * in some cases (e.g., TLS) the negotiated function needs to
  123. * use v->datafd directly and be sure that no data has been
  124. * buffered away in the Bio. since we know the client is waiting
  125. * for our response, it won't have sent any until we respond.
  126. * thus we read the response with vncrdstringx, which goes
  127. * behind bio's back.
  128. */
  129. char*
  130. vncrdstringx(Vnc *v)
  131. {
  132. char tmp[4];
  133. char *s;
  134. ulong len;
  135. assert(Bbuffered(&v->in) == 0);
  136. if(readn(v->datafd, tmp, 4) != 4){
  137. fprint(2, "cannot rdstringx: %r");
  138. vnchungup(v);
  139. }
  140. len = LONG(tmp);
  141. s = malloc(len+1);
  142. assert(s != nil);
  143. if(readn(v->datafd, s, len) != len){
  144. fprint(2, "cannot rdstringx len %lud: %r", len);
  145. vnchungup(v);
  146. }
  147. s[len] = '\0';
  148. return s;
  149. }
  150. void
  151. vncwrstring(Vnc *v, char *s)
  152. {
  153. ulong len;
  154. len = strlen(s);
  155. vncwrlong(v, len);
  156. vncwrbytes(v, s, len);
  157. }
  158. void
  159. vncwrbytes(Vnc *v, void *a, int n)
  160. {
  161. if(Bwrite(&v->out, a, n) < 0){
  162. if(verbose > 1)
  163. fprint(2, "hungup while writing bytes\n");
  164. vnchungup(v);
  165. }
  166. }
  167. void
  168. vncwrlong(Vnc *v, ulong u)
  169. {
  170. uchar buf[4];
  171. buf[0] = u>>24;
  172. buf[1] = u>>16;
  173. buf[2] = u>>8;
  174. buf[3] = u;
  175. vncwrbytes(v, buf, 4);
  176. }
  177. void
  178. vncwrshort(Vnc *v, ushort u)
  179. {
  180. uchar buf[2];
  181. buf[0] = u>>8;
  182. buf[1] = u;
  183. vncwrbytes(v, buf, 2);
  184. }
  185. void
  186. vncwrchar(Vnc *v, uchar c)
  187. {
  188. vncwrbytes(v, &c, 1);
  189. }
  190. void
  191. vncwrpixfmt(Vnc *v, Pixfmt *fmt)
  192. {
  193. vncwrchar(v, fmt->bpp);
  194. vncwrchar(v, fmt->depth);
  195. vncwrchar(v, fmt->bigendian);
  196. vncwrchar(v, fmt->truecolor);
  197. vncwrshort(v, fmt->red.max);
  198. vncwrshort(v, fmt->green.max);
  199. vncwrshort(v, fmt->blue.max);
  200. vncwrchar(v, fmt->red.shift);
  201. vncwrchar(v, fmt->green.shift);
  202. vncwrchar(v, fmt->blue.shift);
  203. vncwrbytes(v, zero, 3);
  204. }
  205. void
  206. vncwrrect(Vnc *v, Rectangle r)
  207. {
  208. vncwrshort(v, r.min.x);
  209. vncwrshort(v, r.min.y);
  210. vncwrshort(v, r.max.x-r.min.x);
  211. vncwrshort(v, r.max.y-r.min.y);
  212. }
  213. void
  214. vncwrpoint(Vnc *v, Point p)
  215. {
  216. vncwrshort(v, p.x);
  217. vncwrshort(v, p.y);
  218. }
  219. void
  220. vnclock(Vnc *v)
  221. {
  222. qlock(v);
  223. }
  224. void
  225. vncunlock(Vnc *v)
  226. {
  227. qunlock(v);
  228. }
  229. void
  230. hexdump(void *a, int n)
  231. {
  232. uchar *p, *ep;
  233. p = a;
  234. ep = p+n;
  235. for(; p<ep; p++)
  236. print("%.2ux ", *p);
  237. print("\n");
  238. }
  239. void
  240. vncgobble(Vnc *v, long n)
  241. {
  242. uchar buf[8192];
  243. long m;
  244. while(n > 0){
  245. m = n;
  246. if(m > sizeof(buf))
  247. m = sizeof(buf);
  248. vncrdbytes(v, buf, m);
  249. n -= m;
  250. }
  251. }