1 /**
2 * xrdp: A Remote Desktop Protocol server.
3 *
4 * Copyright (C) Jay Sorg 2004-2014
5 *
6 * Licensed under the Apache License, Version 2.0 (the "License");
7 * you may not use this file except in compliance with the License.
8 * You may obtain a copy of the License at
9 *
10 * http://www.apache.org/licenses/LICENSE-2.0
11 *
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
17 *
18 * generic transport
19 */
20
21 #if defined(HAVE_CONFIG_H)
22 #include <config_ac.h>
23 #endif
24
25 #include "os_calls.h"
26 #include "string_calls.h"
27 #include "trans.h"
28 #include "arch.h"
29 #include "parse.h"
30 #include "ssl_calls.h"
31 #include "log.h"
32
33 #define MAX_SBYTES 0
34
35 /*****************************************************************************/
36 int
trans_tls_recv(struct trans * self,char * ptr,int len)37 trans_tls_recv(struct trans *self, char *ptr, int len)
38 {
39 if (self->tls == NULL)
40 {
41 return 1;
42 }
43 return ssl_tls_read(self->tls, ptr, len);
44 }
45
46 /*****************************************************************************/
47 int
trans_tls_send(struct trans * self,const char * data,int len)48 trans_tls_send(struct trans *self, const char *data, int len)
49 {
50 if (self->tls == NULL)
51 {
52 return 1;
53 }
54 return ssl_tls_write(self->tls, data, len);
55 }
56
57 /*****************************************************************************/
58 int
trans_tls_can_recv(struct trans * self,int sck,int millis)59 trans_tls_can_recv(struct trans *self, int sck, int millis)
60 {
61 if (self->tls == NULL)
62 {
63 return 1;
64 }
65 return ssl_tls_can_recv(self->tls, sck, millis);
66 }
67
68 /*****************************************************************************/
69 int
trans_tcp_recv(struct trans * self,char * ptr,int len)70 trans_tcp_recv(struct trans *self, char *ptr, int len)
71 {
72 return g_tcp_recv(self->sck, ptr, len, 0);
73 }
74
75 /*****************************************************************************/
76 int
trans_tcp_send(struct trans * self,const char * data,int len)77 trans_tcp_send(struct trans *self, const char *data, int len)
78 {
79 return g_tcp_send(self->sck, data, len, 0);
80 }
81
82 /*****************************************************************************/
83 int
trans_tcp_can_recv(struct trans * self,int sck,int millis)84 trans_tcp_can_recv(struct trans *self, int sck, int millis)
85 {
86 return g_sck_can_recv(sck, millis);
87 }
88
89 /*****************************************************************************/
90 struct trans *
trans_create(int mode,int in_size,int out_size)91 trans_create(int mode, int in_size, int out_size)
92 {
93 struct trans *self = (struct trans *) NULL;
94
95 self = (struct trans *) g_malloc(sizeof(struct trans), 1);
96
97 if (self != NULL)
98 {
99 make_stream(self->in_s);
100 init_stream(self->in_s, in_size);
101 make_stream(self->out_s);
102 init_stream(self->out_s, out_size);
103 self->mode = mode;
104 self->tls = 0;
105 /* assign tcp calls by default */
106 self->trans_recv = trans_tcp_recv;
107 self->trans_send = trans_tcp_send;
108 self->trans_can_recv = trans_tcp_can_recv;
109 }
110
111 return self;
112 }
113
114 /*****************************************************************************/
115 void
trans_delete(struct trans * self)116 trans_delete(struct trans *self)
117 {
118 if (self == 0)
119 {
120 return;
121 }
122
123 free_stream(self->in_s);
124 free_stream(self->out_s);
125
126 if (self->sck > 0)
127 {
128 g_tcp_close(self->sck);
129 }
130
131 self->sck = 0;
132
133 if (self->listen_filename != 0)
134 {
135 g_file_delete(self->listen_filename);
136 g_free(self->listen_filename);
137 }
138
139 if (self->tls != 0)
140 {
141 ssl_tls_delete(self->tls);
142 }
143
144 g_free(self);
145 }
146
147 /*****************************************************************************/
148 void
trans_delete_from_child(struct trans * self)149 trans_delete_from_child(struct trans *self)
150 {
151 if (self == 0)
152 {
153 return;
154 }
155
156 if (self->listen_filename != 0)
157 {
158 g_free(self->listen_filename);
159 self->listen_filename = 0;
160 }
161
162 trans_delete(self);
163 }
164
165 /*****************************************************************************/
166 int
trans_get_wait_objs(struct trans * self,tbus * objs,int * count)167 trans_get_wait_objs(struct trans *self, tbus *objs, int *count)
168 {
169 if (self == 0)
170 {
171 return 1;
172 }
173
174 if (self->status != TRANS_STATUS_UP)
175 {
176 return 1;
177 }
178
179 objs[*count] = self->sck;
180 (*count)++;
181
182 if (self->tls != 0)
183 {
184 if (self->tls->rwo != 0)
185 {
186 objs[*count] = self->tls->rwo;
187 (*count)++;
188 }
189 }
190
191 return 0;
192 }
193
194 /*****************************************************************************/
195 int
trans_get_wait_objs_rw(struct trans * self,tbus * robjs,int * rcount,tbus * wobjs,int * wcount,int * timeout)196 trans_get_wait_objs_rw(struct trans *self, tbus *robjs, int *rcount,
197 tbus *wobjs, int *wcount, int *timeout)
198 {
199 if (self == 0)
200 {
201 return 1;
202 }
203
204 if (self->status != TRANS_STATUS_UP)
205 {
206 return 1;
207 }
208
209 if ((self->si != 0) && (self->si->source[self->my_source] > MAX_SBYTES))
210 {
211 }
212 else
213 {
214 if (trans_get_wait_objs(self, robjs, rcount) != 0)
215 {
216 return 1;
217 }
218 }
219
220 if (self->wait_s != 0)
221 {
222 wobjs[*wcount] = self->sck;
223 (*wcount)++;
224 }
225
226 return 0;
227 }
228
229 /*****************************************************************************/
230 int
trans_send_waiting(struct trans * self,int block)231 trans_send_waiting(struct trans *self, int block)
232 {
233 struct stream *temp_s;
234 int bytes;
235 int sent;
236 int timeout;
237 int cont;
238
239 timeout = block ? 100 : 0;
240 cont = 1;
241 while (cont)
242 {
243 if (self->wait_s != 0)
244 {
245 temp_s = self->wait_s;
246 if (g_tcp_can_send(self->sck, timeout))
247 {
248 bytes = (int) (temp_s->end - temp_s->p);
249 sent = self->trans_send(self, temp_s->p, bytes);
250 if (sent > 0)
251 {
252 temp_s->p += sent;
253 if (temp_s->source != 0)
254 {
255 temp_s->source[0] -= sent;
256 }
257 if (temp_s->p >= temp_s->end)
258 {
259 self->wait_s = temp_s->next;
260 free_stream(temp_s);
261 }
262 }
263 else if (sent == 0)
264 {
265 return 1;
266 }
267 else
268 {
269 if (!g_tcp_last_error_would_block(self->sck))
270 {
271 return 1;
272 }
273 }
274 }
275 else if (block)
276 {
277 /* check for term here */
278 if (self->is_term != 0)
279 {
280 if (self->is_term())
281 {
282 /* term */
283 return 1;
284 }
285 }
286 }
287 }
288 else
289 {
290 break;
291 }
292 cont = block;
293 }
294 return 0;
295 }
296
297 /*****************************************************************************/
298 int
trans_check_wait_objs(struct trans * self)299 trans_check_wait_objs(struct trans *self)
300 {
301 tbus in_sck = (tbus) 0;
302 struct trans *in_trans = (struct trans *) NULL;
303 int read_bytes = 0;
304 int to_read = 0;
305 int read_so_far = 0;
306 int rv = 0;
307 enum xrdp_source cur_source;
308
309 if (self == 0)
310 {
311 return 1;
312 }
313
314 if (self->status != TRANS_STATUS_UP)
315 {
316 return 1;
317 }
318
319 rv = 0;
320
321 if (self->type1 == TRANS_TYPE_LISTENER) /* listening */
322 {
323 if (g_sck_can_recv(self->sck, 0))
324 {
325 in_sck = g_sck_accept(self->sck, self->addr, sizeof(self->addr),
326 self->port, sizeof(self->port));
327
328 if (in_sck == -1)
329 {
330 if (g_tcp_last_error_would_block(self->sck))
331 {
332 /* ok, but shouldn't happen */
333 }
334 else
335 {
336 /* error */
337 self->status = TRANS_STATUS_DOWN;
338 return 1;
339 }
340 }
341
342 if (in_sck != -1)
343 {
344 if (self->trans_conn_in != 0) /* is function assigned */
345 {
346 in_trans = trans_create(self->mode, self->in_s->size,
347 self->out_s->size);
348 in_trans->sck = in_sck;
349 in_trans->type1 = TRANS_TYPE_SERVER;
350 in_trans->status = TRANS_STATUS_UP;
351 in_trans->is_term = self->is_term;
352 g_strncpy(in_trans->addr, self->addr,
353 sizeof(self->addr) - 1);
354 g_strncpy(in_trans->port, self->port,
355 sizeof(self->port) - 1);
356 g_sck_set_non_blocking(in_sck);
357 if (self->trans_conn_in(self, in_trans) != 0)
358 {
359 trans_delete(in_trans);
360 }
361 }
362 else
363 {
364 g_tcp_close(in_sck);
365 }
366 }
367 }
368 }
369 else /* connected server or client (2 or 3) */
370 {
371 if (self->si != 0 && self->si->source[self->my_source] > MAX_SBYTES)
372 {
373 }
374 else if (self->trans_can_recv(self, self->sck, 0))
375 {
376 cur_source = XRDP_SOURCE_NONE;
377 if (self->si != 0)
378 {
379 cur_source = self->si->cur_source;
380 self->si->cur_source = self->my_source;
381 }
382 read_so_far = (int) (self->in_s->end - self->in_s->data);
383 to_read = self->header_size - read_so_far;
384
385 if (to_read > 0)
386 {
387 read_bytes = self->trans_recv(self, self->in_s->end, to_read);
388
389 if (read_bytes == -1)
390 {
391 if (g_tcp_last_error_would_block(self->sck))
392 {
393 /* ok, but shouldn't happen */
394 }
395 else
396 {
397 /* error */
398 self->status = TRANS_STATUS_DOWN;
399 if (self->si != 0)
400 {
401 self->si->cur_source = cur_source;
402 }
403 return 1;
404 }
405 }
406 else if (read_bytes == 0)
407 {
408 /* error */
409 self->status = TRANS_STATUS_DOWN;
410 if (self->si != 0)
411 {
412 self->si->cur_source = cur_source;
413 }
414 return 1;
415 }
416 else
417 {
418 self->in_s->end += read_bytes;
419 }
420 }
421
422 read_so_far = (int) (self->in_s->end - self->in_s->data);
423
424 if (read_so_far == self->header_size)
425 {
426 if (self->trans_data_in != 0)
427 {
428 rv = self->trans_data_in(self);
429 if (self->no_stream_init_on_data_in == 0)
430 {
431 init_stream(self->in_s, 0);
432 }
433 }
434 }
435 if (self->si != 0)
436 {
437 self->si->cur_source = cur_source;
438 }
439 }
440 if (trans_send_waiting(self, 0) != 0)
441 {
442 /* error */
443 self->status = TRANS_STATUS_DOWN;
444 return 1;
445 }
446 }
447
448 return rv;
449 }
450
451 /*****************************************************************************/
452 int
trans_force_read_s(struct trans * self,struct stream * in_s,int size)453 trans_force_read_s(struct trans *self, struct stream *in_s, int size)
454 {
455 int rcvd;
456
457 if (self->status != TRANS_STATUS_UP ||
458 size < 0 || !s_check_rem_out(in_s, size))
459 {
460 return 1;
461 }
462
463 while (size > 0)
464 {
465 rcvd = self->trans_recv(self, in_s->end, size);
466 if (rcvd == -1)
467 {
468 if (g_tcp_last_error_would_block(self->sck))
469 {
470 if (!self->trans_can_recv(self, self->sck, 100))
471 {
472 /* check for term here */
473 if (self->is_term != 0)
474 {
475 if (self->is_term())
476 {
477 /* term */
478 self->status = TRANS_STATUS_DOWN;
479 return 1;
480 }
481 }
482 }
483 }
484 else
485 {
486 /* error */
487 self->status = TRANS_STATUS_DOWN;
488 return 1;
489 }
490 }
491 else if (rcvd == 0)
492 {
493 /* error */
494 self->status = TRANS_STATUS_DOWN;
495 return 1;
496 }
497 else
498 {
499 in_s->end += rcvd;
500 size -= rcvd;
501 }
502 }
503 return 0;
504 }
505
506 /*****************************************************************************/
507 int
trans_force_read(struct trans * self,int size)508 trans_force_read(struct trans *self, int size)
509 {
510 return trans_force_read_s(self, self->in_s, size);
511 }
512
513 /*****************************************************************************/
514 int
trans_force_write_s(struct trans * self,struct stream * out_s)515 trans_force_write_s(struct trans *self, struct stream *out_s)
516 {
517 int size;
518 int total;
519 int sent;
520
521 if (self->status != TRANS_STATUS_UP)
522 {
523 return 1;
524 }
525 size = (int) (out_s->end - out_s->data);
526 total = 0;
527 if (trans_send_waiting(self, 1) != 0)
528 {
529 self->status = TRANS_STATUS_DOWN;
530 return 1;
531 }
532 while (total < size)
533 {
534 sent = self->trans_send(self, out_s->data + total, size - total);
535 if (sent == -1)
536 {
537 if (g_tcp_last_error_would_block(self->sck))
538 {
539 if (!g_tcp_can_send(self->sck, 100))
540 {
541 /* check for term here */
542 if (self->is_term != 0)
543 {
544 if (self->is_term())
545 {
546 /* term */
547 self->status = TRANS_STATUS_DOWN;
548 return 1;
549 }
550 }
551 }
552 }
553 else
554 {
555 /* error */
556 self->status = TRANS_STATUS_DOWN;
557 return 1;
558 }
559 }
560 else if (sent == 0)
561 {
562 /* error */
563 self->status = TRANS_STATUS_DOWN;
564 return 1;
565 }
566 else
567 {
568 total = total + sent;
569 }
570 }
571 return 0;
572 }
573
574 /*****************************************************************************/
575 int
trans_force_write(struct trans * self)576 trans_force_write(struct trans *self)
577 {
578 return trans_force_write_s(self, self->out_s);
579 }
580
581 /*****************************************************************************/
582 int
trans_write_copy_s(struct trans * self,struct stream * out_s)583 trans_write_copy_s(struct trans *self, struct stream *out_s)
584 {
585 int size;
586 int sent;
587 struct stream *wait_s;
588 struct stream *temp_s;
589 char *out_data;
590
591 if (self->status != TRANS_STATUS_UP)
592 {
593 return 1;
594 }
595 /* try to send any left over */
596 if (trans_send_waiting(self, 0) != 0)
597 {
598 /* error */
599 self->status = TRANS_STATUS_DOWN;
600 return 1;
601 }
602 out_data = out_s->data;
603 sent = 0;
604 size = (int) (out_s->end - out_s->data);
605 if (self->wait_s == 0)
606 {
607 /* if no left over, try to send this new data */
608 if (g_tcp_can_send(self->sck, 0))
609 {
610 sent = self->trans_send(self, out_s->data, size);
611 if (sent > 0)
612 {
613 out_data += sent;
614 size -= sent;
615 }
616 else if (sent == 0)
617 {
618 return 1;
619 }
620 else
621 {
622 if (!g_tcp_last_error_would_block(self->sck))
623 {
624 return 1;
625 }
626 }
627 }
628 }
629 if (size < 1)
630 {
631 return 0;
632 }
633 /* did not send right away, have to copy */
634 make_stream(wait_s);
635 init_stream(wait_s, size);
636 if (self->si != 0)
637 {
638 if ((self->si->cur_source != XRDP_SOURCE_NONE) &&
639 (self->si->cur_source != self->my_source))
640 {
641 self->si->source[self->si->cur_source] += size;
642 wait_s->source = self->si->source + self->si->cur_source;
643 }
644 }
645 out_uint8a(wait_s, out_data, size);
646 s_mark_end(wait_s);
647 wait_s->p = wait_s->data;
648 if (self->wait_s == 0)
649 {
650 self->wait_s = wait_s;
651 }
652 else
653 {
654 temp_s = self->wait_s;
655 while (temp_s->next != 0)
656 {
657 temp_s = temp_s->next;
658 }
659 temp_s->next = wait_s;
660 }
661 return 0;
662 }
663
664 /*****************************************************************************/
665 int
trans_write_copy(struct trans * self)666 trans_write_copy(struct trans *self)
667 {
668 return trans_write_copy_s(self, self->out_s);
669 }
670
671 /*****************************************************************************/
672 int
trans_connect(struct trans * self,const char * server,const char * port,int timeout)673 trans_connect(struct trans *self, const char *server, const char *port,
674 int timeout)
675 {
676 int error;
677 int now;
678 int start_time;
679
680 start_time = g_time3();
681
682 if (self->sck != 0)
683 {
684 g_tcp_close(self->sck);
685 self->sck = 0;
686 }
687
688 if (self->mode == TRANS_MODE_TCP) /* tcp */
689 {
690 self->sck = g_tcp_socket();
691 if (self->sck < 0)
692 {
693 self->status = TRANS_STATUS_DOWN;
694 return 1;
695 }
696 g_tcp_set_non_blocking(self->sck);
697 while (1)
698 {
699 error = g_tcp_connect(self->sck, server, port);
700 if (error == 0)
701 {
702 break;
703 }
704 else
705 {
706 if (timeout < 1)
707 {
708 self->status = TRANS_STATUS_DOWN;
709 return 1;
710 }
711 now = g_time3();
712 if (now - start_time < timeout)
713 {
714 g_sleep(100);
715 }
716 else
717 {
718 self->status = TRANS_STATUS_DOWN;
719 return 1;
720 }
721 if (self->is_term != NULL)
722 {
723 if (self->is_term())
724 {
725 self->status = TRANS_STATUS_DOWN;
726 return 1;
727 }
728 }
729 }
730 }
731 }
732 else if (self->mode == TRANS_MODE_UNIX) /* unix socket */
733 {
734 self->sck = g_tcp_local_socket();
735 if (self->sck < 0)
736 {
737 self->status = TRANS_STATUS_DOWN;
738 return 1;
739 }
740 g_tcp_set_non_blocking(self->sck);
741 while (1)
742 {
743 error = g_tcp_local_connect(self->sck, port);
744 if (error == 0)
745 {
746 break;
747 }
748 else
749 {
750 if (timeout < 1)
751 {
752 self->status = TRANS_STATUS_DOWN;
753 return 1;
754 }
755 now = g_time3();
756 if (now - start_time < timeout)
757 {
758 g_sleep(100);
759 }
760 else
761 {
762 self->status = TRANS_STATUS_DOWN;
763 return 1;
764 }
765 if (self->is_term != NULL)
766 {
767 if (self->is_term())
768 {
769 self->status = TRANS_STATUS_DOWN;
770 return 1;
771 }
772 }
773 }
774 }
775 }
776 else
777 {
778 self->status = TRANS_STATUS_DOWN;
779 return 1;
780 }
781
782 if (error == -1)
783 {
784 if (g_tcp_last_error_would_block(self->sck))
785 {
786 now = g_time3();
787 if (now - start_time < timeout)
788 {
789 timeout = timeout - (now - start_time);
790 }
791 else
792 {
793 timeout = 0;
794 }
795 if (g_tcp_can_send(self->sck, timeout))
796 {
797 self->status = TRANS_STATUS_UP; /* ok */
798 self->type1 = TRANS_TYPE_CLIENT; /* client */
799 return 0;
800 }
801 }
802
803 return 1;
804 }
805
806 self->status = TRANS_STATUS_UP; /* ok */
807 self->type1 = TRANS_TYPE_CLIENT; /* client */
808 return 0;
809 }
810
811 /*****************************************************************************/
812
813 /**
814 * @return 0 on success, 1 on failure
815 */
816 int
trans_listen_address(struct trans * self,char * port,const char * address)817 trans_listen_address(struct trans *self, char *port, const char *address)
818 {
819 if (self->sck != 0)
820 {
821 g_tcp_close(self->sck);
822 }
823
824 if (self->mode == TRANS_MODE_TCP) /* tcp */
825 {
826 self->sck = g_tcp_socket();
827 if (self->sck < 0)
828 {
829 return 1;
830 }
831
832 g_tcp_set_non_blocking(self->sck);
833
834 if (g_tcp_bind_address(self->sck, port, address) == 0)
835 {
836 if (g_tcp_listen(self->sck) == 0)
837 {
838 self->status = TRANS_STATUS_UP; /* ok */
839 self->type1 = TRANS_TYPE_LISTENER; /* listener */
840 return 0;
841 }
842 }
843 }
844 else if (self->mode == TRANS_MODE_UNIX) /* unix socket */
845 {
846 g_free(self->listen_filename);
847 self->listen_filename = 0;
848 g_file_delete(port);
849
850 self->sck = g_tcp_local_socket();
851 if (self->sck < 0)
852 {
853 return 1;
854 }
855
856 g_tcp_set_non_blocking(self->sck);
857
858 if (g_tcp_local_bind(self->sck, port) == 0)
859 {
860 self->listen_filename = g_strdup(port);
861
862 if (g_tcp_listen(self->sck) == 0)
863 {
864 g_chmod_hex(port, 0x0660);
865 self->status = TRANS_STATUS_UP; /* ok */
866 self->type1 = TRANS_TYPE_LISTENER; /* listener */
867 return 0;
868 }
869 }
870 }
871 else if (self->mode == TRANS_MODE_VSOCK) /* vsock socket */
872 {
873 self->sck = g_sck_vsock_socket();
874 if (self->sck < 0)
875 {
876 return 1;
877 }
878
879 g_tcp_set_non_blocking(self->sck);
880
881 if (g_sck_vsock_bind_address(self->sck, port, address) == 0)
882 {
883 if (g_tcp_listen(self->sck) == 0)
884 {
885 self->status = TRANS_STATUS_UP; /* ok */
886 self->type1 = TRANS_TYPE_LISTENER; /* listener */
887 return 0;
888 }
889 }
890 }
891 else if (self->mode == TRANS_MODE_TCP4) /* tcp4 */
892 {
893 self->sck = g_tcp4_socket();
894 if (self->sck < 0)
895 {
896 return 1;
897 }
898 g_tcp_set_non_blocking(self->sck);
899 if (g_tcp4_bind_address(self->sck, port, address) == 0)
900 {
901 if (g_tcp_listen(self->sck) == 0)
902 {
903 self->status = TRANS_STATUS_UP; /* ok */
904 self->type1 = TRANS_TYPE_LISTENER; /* listener */
905 return 0;
906 }
907 }
908 }
909 else if (self->mode == TRANS_MODE_TCP6) /* tcp6 */
910 {
911 self->sck = g_tcp6_socket();
912 if (self->sck < 0)
913 {
914 return 1;
915 }
916 g_tcp_set_non_blocking(self->sck);
917 if (g_tcp6_bind_address(self->sck, port, address) == 0)
918 {
919 if (g_tcp_listen(self->sck) == 0)
920 {
921 self->status = TRANS_STATUS_UP; /* ok */
922 self->type1 = TRANS_TYPE_LISTENER; /* listener */
923 return 0;
924 }
925 }
926 }
927 return 1;
928 }
929
930 /*****************************************************************************/
931 int
trans_listen(struct trans * self,char * port)932 trans_listen(struct trans *self, char *port)
933 {
934 return trans_listen_address(self, port, "0.0.0.0");
935 }
936
937 /*****************************************************************************/
938 struct stream *
trans_get_in_s(struct trans * self)939 trans_get_in_s(struct trans *self)
940 {
941 struct stream *rv = (struct stream *) NULL;
942
943 if (self == NULL)
944 {
945 rv = (struct stream *) NULL;
946 }
947 else
948 {
949 rv = self->in_s;
950 }
951
952 return rv;
953 }
954
955 /*****************************************************************************/
956 struct stream *
trans_get_out_s(struct trans * self,int size)957 trans_get_out_s(struct trans *self, int size)
958 {
959 struct stream *rv = (struct stream *) NULL;
960
961 if (self == NULL)
962 {
963 rv = (struct stream *) NULL;
964 }
965 else
966 {
967 init_stream(self->out_s, size);
968 rv = self->out_s;
969 }
970
971 return rv;
972 }
973
974 /*****************************************************************************/
975 /* returns error */
976 int
trans_set_tls_mode(struct trans * self,const char * key,const char * cert,long ssl_protocols,const char * tls_ciphers)977 trans_set_tls_mode(struct trans *self, const char *key, const char *cert,
978 long ssl_protocols, const char *tls_ciphers)
979 {
980 self->tls = ssl_tls_create(self, key, cert);
981 if (self->tls == NULL)
982 {
983 LOG(LOG_LEVEL_ERROR, "trans_set_tls_mode: ssl_tls_create malloc error");
984 return 1;
985 }
986
987 if (ssl_tls_accept(self->tls, ssl_protocols, tls_ciphers) != 0)
988 {
989 LOG(LOG_LEVEL_ERROR, "trans_set_tls_mode: ssl_tls_accept failed");
990 return 1;
991 }
992
993 /* assign tls functions */
994 self->trans_recv = trans_tls_recv;
995 self->trans_send = trans_tls_send;
996 self->trans_can_recv = trans_tls_can_recv;
997
998 self->ssl_protocol = ssl_get_version(self->tls->ssl);
999 self->cipher_name = ssl_get_cipher_name(self->tls->ssl);
1000
1001 return 0;
1002 }
1003
1004 /*****************************************************************************/
1005 /* returns error */
1006 int
trans_shutdown_tls_mode(struct trans * self)1007 trans_shutdown_tls_mode(struct trans *self)
1008 {
1009 if (self->tls != NULL)
1010 {
1011 return ssl_tls_disconnect(self->tls);
1012 }
1013
1014 /* assign callback back to tcp cal */
1015 self->trans_recv = trans_tcp_recv;
1016 self->trans_send = trans_tcp_send;
1017 self->trans_can_recv = trans_tcp_can_recv;
1018
1019 return 0;
1020 }
1021