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