VirtualBox

source: vbox/trunk/src/libs/openssl-1.1.1l/apps/vms_term_sock.c@ 92324

Last change on this file since 92324 was 91772, checked in by vboxsync, 3 years ago

openssl-1.1.1l: Applied and adjusted our OpenSSL changes to 1.1.1l. bugref:10126

File size: 17.3 KB
Line 
1/*
2 * Copyright 2016 The OpenSSL Project Authors. All Rights Reserved.
3 * Copyright 2016 VMS Software, Inc. All Rights Reserved.
4 *
5 * Licensed under the OpenSSL license (the "License"). You may not use
6 * this file except in compliance with the License. You can obtain a copy
7 * in the file LICENSE in the source distribution or at
8 * https://www.openssl.org/source/license.html
9 */
10
11#ifdef __VMS
12# define OPENSSL_SYS_VMS
13# pragma message disable DOLLARID
14
15
16# include <openssl/opensslconf.h>
17
18# if !defined(_POSIX_C_SOURCE) && defined(OPENSSL_SYS_VMS)
19/*
20 * On VMS, you need to define this to get the declaration of fileno(). The
21 * value 2 is to make sure no function defined in POSIX-2 is left undefined.
22 */
23# define _POSIX_C_SOURCE 2
24# endif
25
26# include <stdio.h>
27
28# undef _POSIX_C_SOURCE
29
30# include <sys/types.h>
31# include <sys/socket.h>
32# include <netinet/in.h>
33# include <inet.h>
34# include <unistd.h>
35# include <string.h>
36# include <errno.h>
37# include <starlet.h>
38# include <iodef.h>
39# ifdef __alpha
40# include <iosbdef.h>
41# else
42typedef struct _iosb { /* Copied from IOSBDEF.H for Alpha */
43# pragma __nomember_alignment
44 __union {
45 __struct {
46 unsigned short int iosb$w_status; /* Final I/O status */
47 __union {
48 __struct { /* 16-bit byte count variant */
49 unsigned short int iosb$w_bcnt; /* 16-bit byte count */
50 __union {
51 unsigned int iosb$l_dev_depend; /* 32-bit device dependent info */
52 unsigned int iosb$l_pid; /* 32-bit pid */
53 } iosb$r_l;
54 } iosb$r_bcnt_16;
55 __struct { /* 32-bit byte count variant */
56 unsigned int iosb$l_bcnt; /* 32-bit byte count (unaligned) */
57 unsigned short int iosb$w_dev_depend_high; /* 16-bit device dependent info */
58 } iosb$r_bcnt_32;
59 } iosb$r_devdepend;
60 } iosb$r_io_64;
61 __struct {
62 __union {
63 unsigned int iosb$l_getxxi_status; /* Final GETxxI status */
64 unsigned int iosb$l_reg_status; /* Final $Registry status */
65 } iosb$r_l_status;
66 unsigned int iosb$l_reserved; /* Reserved field */
67 } iosb$r_get_64;
68 } iosb$r_io_get;
69} IOSB;
70
71# if !defined(__VAXC)
72# define iosb$w_status iosb$r_io_get.iosb$r_io_64.iosb$w_status
73# define iosb$w_bcnt iosb$r_io_get.iosb$r_io_64.iosb$r_devdepend.iosb$r_bcnt_16.iosb$w_bcnt
74# define iosb$r_l iosb$r_io_get.iosb$r_io_64.iosb$r_devdepend.iosb$r_bcnt_16.iosb$r_l
75# define iosb$l_dev_depend iosb$r_l.iosb$l_dev_depend
76# define iosb$l_pid iosb$r_l.iosb$l_pid
77# define iosb$l_bcnt iosb$r_io_get.iosb$r_io_64.iosb$r_devdepend.iosb$r_bcnt_32.iosb$l_bcnt
78# define iosb$w_dev_depend_high iosb$r_io_get.iosb$r_io_64.iosb$r_devdepend.iosb$r_bcnt_32.iosb$w_dev_depend_high
79# define iosb$l_getxxi_status iosb$r_io_get.iosb$r_get_64.iosb$r_l_status.iosb$l_getxxi_status
80# define iosb$l_reg_status iosb$r_io_get.iosb$r_get_64.iosb$r_l_status.iosb$l_reg_status
81# endif /* #if !defined(__VAXC) */
82
83# endif /* End of IOSBDEF */
84
85# include <efndef.h>
86# include <stdlib.h>
87# include <ssdef.h>
88# include <time.h>
89# include <stdarg.h>
90# include <descrip.h>
91
92# include "vms_term_sock.h"
93
94# ifdef __alpha
95static struct _iosb TerminalDeviceIosb;
96# else
97IOSB TerminalDeviceIosb;
98# endif
99
100static char TerminalDeviceBuff[255 + 2];
101static int TerminalSocketPair[2] = {0, 0};
102static unsigned short TerminalDeviceChan = 0;
103
104static int CreateSocketPair (int, int, int, int *);
105static void SocketPairTimeoutAst (int);
106static int TerminalDeviceAst (int);
107static void LogMessage (char *, ...);
108
109/*
110** Socket Pair Timeout Value (must be 0-59 seconds)
111*/
112# define SOCKET_PAIR_TIMEOUT_VALUE 20
113
114/*
115** Socket Pair Timeout Block which is passed to timeout AST
116*/
117typedef struct _SocketPairTimeoutBlock {
118 unsigned short SockChan1;
119 unsigned short SockChan2;
120} SPTB;
121
122# ifdef TERM_SOCK_TEST
123
124
125/*----------------------------------------------------------------------------*/
126/* */
127/*----------------------------------------------------------------------------*/
128int main (int argc, char *argv[], char *envp[])
129{
130 char TermBuff[80];
131 int TermSock,
132 status,
133 len;
134
135 LogMessage ("Enter 'q' or 'Q' to quit ...");
136 while (strcasecmp (TermBuff, "Q")) {
137 /*
138 ** Create the terminal socket
139 */
140 status = TerminalSocket (TERM_SOCK_CREATE, &TermSock);
141 if (status != TERM_SOCK_SUCCESS)
142 exit (1);
143
144 /*
145 ** Process the terminal input
146 */
147 LogMessage ("Waiting on terminal I/O ...\n");
148 len = recv (TermSock, TermBuff, sizeof(TermBuff), 0) ;
149 TermBuff[len] = '\0';
150 LogMessage ("Received terminal I/O [%s]", TermBuff);
151
152 /*
153 ** Delete the terminal socket
154 */
155 status = TerminalSocket (TERM_SOCK_DELETE, &TermSock);
156 if (status != TERM_SOCK_SUCCESS)
157 exit (1);
158 }
159
160 return 1;
161
162}
163# endif
164
165
166/*----------------------------------------------------------------------------*/
167/* */
168/*----------------------------------------------------------------------------*/
169int TerminalSocket (int FunctionCode, int *ReturnSocket)
170{
171 int status;
172 $DESCRIPTOR (TerminalDeviceDesc, "SYS$COMMAND");
173
174 /*
175 ** Process the requested function code
176 */
177 switch (FunctionCode) {
178 case TERM_SOCK_CREATE:
179 /*
180 ** Create a socket pair
181 */
182 status = CreateSocketPair (AF_INET, SOCK_STREAM, 0, TerminalSocketPair);
183 if (status == -1) {
184 LogMessage ("TerminalSocket: CreateSocketPair () - %08X", status);
185 if (TerminalSocketPair[0])
186 close (TerminalSocketPair[0]);
187 if (TerminalSocketPair[1])
188 close (TerminalSocketPair[1]);
189 return TERM_SOCK_FAILURE;
190 }
191
192 /*
193 ** Assign a channel to the terminal device
194 */
195 status = sys$assign (&TerminalDeviceDesc,
196 &TerminalDeviceChan,
197 0, 0, 0);
198 if (! (status & 1)) {
199 LogMessage ("TerminalSocket: SYS$ASSIGN () - %08X", status);
200 close (TerminalSocketPair[0]);
201 close (TerminalSocketPair[1]);
202 return TERM_SOCK_FAILURE;
203 }
204
205 /*
206 ** Queue an async IO to the terminal device
207 */
208 status = sys$qio (EFN$C_ENF,
209 TerminalDeviceChan,
210 IO$_READVBLK,
211 &TerminalDeviceIosb,
212 TerminalDeviceAst,
213 0,
214 TerminalDeviceBuff,
215 sizeof(TerminalDeviceBuff) - 2,
216 0, 0, 0, 0);
217 if (! (status & 1)) {
218 LogMessage ("TerminalSocket: SYS$QIO () - %08X", status);
219 close (TerminalSocketPair[0]);
220 close (TerminalSocketPair[1]);
221 return TERM_SOCK_FAILURE;
222 }
223
224 /*
225 ** Return the input side of the socket pair
226 */
227 *ReturnSocket = TerminalSocketPair[1];
228 break;
229
230 case TERM_SOCK_DELETE:
231 /*
232 ** Cancel any pending IO on the terminal channel
233 */
234 status = sys$cancel (TerminalDeviceChan);
235 if (! (status & 1)) {
236 LogMessage ("TerminalSocket: SYS$CANCEL () - %08X", status);
237 close (TerminalSocketPair[0]);
238 close (TerminalSocketPair[1]);
239 return TERM_SOCK_FAILURE;
240 }
241
242 /*
243 ** Deassign the terminal channel
244 */
245 status = sys$dassgn (TerminalDeviceChan);
246 if (! (status & 1)) {
247 LogMessage ("TerminalSocket: SYS$DASSGN () - %08X", status);
248 close (TerminalSocketPair[0]);
249 close (TerminalSocketPair[1]);
250 return TERM_SOCK_FAILURE;
251 }
252
253 /*
254 ** Close the terminal socket pair
255 */
256 close (TerminalSocketPair[0]);
257 close (TerminalSocketPair[1]);
258
259 /*
260 ** Return the initialized socket
261 */
262 *ReturnSocket = 0;
263 break;
264
265 default:
266 /*
267 ** Invalid function code
268 */
269 LogMessage ("TerminalSocket: Invalid Function Code - %d", FunctionCode);
270 return TERM_SOCK_FAILURE;
271 break;
272 }
273
274 /*
275 ** Return success
276 */
277 return TERM_SOCK_SUCCESS;
278
279}
280
281
282/*----------------------------------------------------------------------------*/
283/* */
284/*----------------------------------------------------------------------------*/
285static int CreateSocketPair (int SocketFamily,
286 int SocketType,
287 int SocketProtocol,
288 int *SocketPair)
289{
290 struct dsc$descriptor AscTimeDesc = {0, DSC$K_DTYPE_T, DSC$K_CLASS_S, NULL};
291 static const char* LocalHostAddr = {"127.0.0.1"};
292 unsigned short TcpAcceptChan = 0,
293 TcpDeviceChan = 0;
294 unsigned long BinTimeBuff[2];
295 struct sockaddr_in sin;
296 char AscTimeBuff[32];
297 short LocalHostPort;
298 int status;
299 unsigned int slen;
300
301# ifdef __alpha
302 struct _iosb iosb;
303# else
304 IOSB iosb;
305# endif
306
307 int SockDesc1 = 0,
308 SockDesc2 = 0;
309 SPTB sptb;
310 $DESCRIPTOR (TcpDeviceDesc, "TCPIP$DEVICE");
311
312 /*
313 ** Create a socket
314 */
315 SockDesc1 = socket (SocketFamily, SocketType, 0);
316 if (SockDesc1 < 0) {
317 LogMessage ("CreateSocketPair: socket () - %d", errno);
318 return -1;
319 }
320
321 /*
322 ** Initialize the socket information
323 */
324 slen = sizeof(sin);
325 memset ((char *) &sin, 0, slen);
326 sin.sin_family = SocketFamily;
327 sin.sin_addr.s_addr = inet_addr (LocalHostAddr);
328 sin.sin_port = 0;
329
330 /*
331 ** Bind the socket to the local IP
332 */
333 status = bind (SockDesc1, (struct sockaddr *) &sin, slen);
334 if (status < 0) {
335 LogMessage ("CreateSocketPair: bind () - %d", errno);
336 close (SockDesc1);
337 return -1;
338 }
339
340 /*
341 ** Get the socket name so we can save the port number
342 */
343 status = getsockname (SockDesc1, (struct sockaddr *) &sin, &slen);
344 if (status < 0) {
345 LogMessage ("CreateSocketPair: getsockname () - %d", errno);
346 close (SockDesc1);
347 return -1;
348 } else
349 LocalHostPort = sin.sin_port;
350
351 /*
352 ** Setup a listen for the socket
353 */
354 listen (SockDesc1, 5);
355
356 /*
357 ** Get the binary (64-bit) time of the specified timeout value
358 */
359 sprintf (AscTimeBuff, "0 0:0:%02d.00", SOCKET_PAIR_TIMEOUT_VALUE);
360 AscTimeDesc.dsc$w_length = strlen (AscTimeBuff);
361 AscTimeDesc.dsc$a_pointer = AscTimeBuff;
362 status = sys$bintim (&AscTimeDesc, BinTimeBuff);
363 if (! (status & 1)) {
364 LogMessage ("CreateSocketPair: SYS$BINTIM () - %08X", status);
365 close (SockDesc1);
366 return -1;
367 }
368
369 /*
370 ** Assign another channel to the TCP/IP device for the accept.
371 ** This is the channel that ends up being connected to.
372 */
373 status = sys$assign (&TcpDeviceDesc, &TcpDeviceChan, 0, 0, 0);
374 if (! (status & 1)) {
375 LogMessage ("CreateSocketPair: SYS$ASSIGN () - %08X", status);
376 close (SockDesc1);
377 return -1;
378 }
379
380 /*
381 ** Get the channel of the first socket for the accept
382 */
383 TcpAcceptChan = decc$get_sdc (SockDesc1);
384
385 /*
386 ** Perform the accept using $QIO so we can do this asynchronously
387 */
388 status = sys$qio (EFN$C_ENF,
389 TcpAcceptChan,
390 IO$_ACCESS | IO$M_ACCEPT,
391 &iosb,
392 0, 0, 0, 0, 0,
393 &TcpDeviceChan,
394 0, 0);
395 if (! (status & 1)) {
396 LogMessage ("CreateSocketPair: SYS$QIO () - %08X", status);
397 close (SockDesc1);
398 sys$dassgn (TcpDeviceChan);
399 return -1;
400 }
401
402 /*
403 ** Create the second socket to do the connect
404 */
405 SockDesc2 = socket (SocketFamily, SocketType, 0);
406 if (SockDesc2 < 0) {
407 LogMessage ("CreateSocketPair: socket () - %d", errno);
408 sys$cancel (TcpAcceptChan);
409 close (SockDesc1);
410 sys$dassgn (TcpDeviceChan);
411 return (-1) ;
412 }
413
414 /*
415 ** Setup the Socket Pair Timeout Block
416 */
417 sptb.SockChan1 = TcpAcceptChan;
418 sptb.SockChan2 = decc$get_sdc (SockDesc2);
419
420 /*
421 ** Before we block on the connect, set a timer that can cancel I/O on our
422 ** two sockets if it never connects.
423 */
424 status = sys$setimr (EFN$C_ENF,
425 BinTimeBuff,
426 SocketPairTimeoutAst,
427 &sptb,
428 0);
429 if (! (status & 1)) {
430 LogMessage ("CreateSocketPair: SYS$SETIMR () - %08X", status);
431 sys$cancel (TcpAcceptChan);
432 close (SockDesc1);
433 close (SockDesc2);
434 sys$dassgn (TcpDeviceChan);
435 return -1;
436 }
437
438 /*
439 ** Now issue the connect
440 */
441 memset ((char *) &sin, 0, sizeof(sin)) ;
442 sin.sin_family = SocketFamily;
443 sin.sin_addr.s_addr = inet_addr (LocalHostAddr) ;
444 sin.sin_port = LocalHostPort ;
445
446 status = connect (SockDesc2, (struct sockaddr *) &sin, sizeof(sin));
447 if (status < 0 ) {
448 LogMessage ("CreateSocketPair: connect () - %d", errno);
449 sys$cantim (&sptb, 0);
450 sys$cancel (TcpAcceptChan);
451 close (SockDesc1);
452 close (SockDesc2);
453 sys$dassgn (TcpDeviceChan);
454 return -1;
455 }
456
457 /*
458 ** Wait for the asynch $QIO to finish. Note that if the I/O was aborted
459 ** (SS$_ABORT), then we probably canceled it from the AST routine - so log
460 ** a timeout.
461 */
462 status = sys$synch (EFN$C_ENF, &iosb);
463 if (! (iosb.iosb$w_status & 1)) {
464 if (iosb.iosb$w_status == SS$_ABORT)
465 LogMessage ("CreateSocketPair: SYS$QIO(iosb) timeout");
466 else {
467 LogMessage ("CreateSocketPair: SYS$QIO(iosb) - %d",
468 iosb.iosb$w_status);
469 sys$cantim (&sptb, 0);
470 }
471 close (SockDesc1);
472 close (SockDesc2);
473 sys$dassgn (TcpDeviceChan);
474 return -1;
475 }
476
477 /*
478 ** Here we're successfully connected, so cancel the timer, convert the
479 ** I/O channel to a socket fd, close the listener socket and return the
480 ** connected pair.
481 */
482 sys$cantim (&sptb, 0);
483
484 close (SockDesc1) ;
485 SocketPair[0] = SockDesc2 ;
486 SocketPair[1] = socket_fd (TcpDeviceChan);
487
488 return (0) ;
489
490}
491
492
493/*----------------------------------------------------------------------------*/
494/* */
495/*----------------------------------------------------------------------------*/
496static void SocketPairTimeoutAst (int astparm)
497{
498 SPTB *sptb = (SPTB *) astparm;
499
500 sys$cancel (sptb->SockChan2); /* Cancel the connect() */
501 sys$cancel (sptb->SockChan1); /* Cancel the accept() */
502
503 return;
504
505}
506
507
508/*----------------------------------------------------------------------------*/
509/* */
510/*----------------------------------------------------------------------------*/
511static int TerminalDeviceAst (int astparm)
512{
513 int status;
514
515 /*
516 ** Terminate the terminal buffer
517 */
518 TerminalDeviceBuff[TerminalDeviceIosb.iosb$w_bcnt] = '\0';
519 strcat (TerminalDeviceBuff, "\n");
520
521 /*
522 ** Send the data read from the terminal device through the socket pair
523 */
524 send (TerminalSocketPair[0], TerminalDeviceBuff,
525 TerminalDeviceIosb.iosb$w_bcnt + 1, 0);
526
527 /*
528 ** Queue another async IO to the terminal device
529 */
530 status = sys$qio (EFN$C_ENF,
531 TerminalDeviceChan,
532 IO$_READVBLK,
533 &TerminalDeviceIosb,
534 TerminalDeviceAst,
535 0,
536 TerminalDeviceBuff,
537 sizeof(TerminalDeviceBuff) - 1,
538 0, 0, 0, 0);
539
540 /*
541 ** Return status
542 */
543 return status;
544
545}
546
547
548/*----------------------------------------------------------------------------*/
549/* */
550/*----------------------------------------------------------------------------*/
551static void LogMessage (char *msg, ...)
552{
553 char *Month[] = {"Jan", "Feb", "Mar", "Apr", "May", "Jun",
554 "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"};
555 static unsigned int pid = 0;
556 va_list args;
557 time_t CurTime;
558 struct tm *LocTime;
559 char MsgBuff[256];
560
561 /*
562 ** Get the process pid
563 */
564 if (pid == 0)
565 pid = getpid ();
566
567 /*
568 ** Convert the current time into local time
569 */
570 CurTime = time (NULL);
571 LocTime = localtime (&CurTime);
572
573 /*
574 ** Format the message buffer
575 */
576 sprintf (MsgBuff, "%02d-%s-%04d %02d:%02d:%02d [%08X] %s\n",
577 LocTime->tm_mday, Month[LocTime->tm_mon],
578 (LocTime->tm_year + 1900), LocTime->tm_hour, LocTime->tm_min,
579 LocTime->tm_sec, pid, msg);
580
581 /*
582 ** Get any variable arguments and add them to the print of the message
583 ** buffer
584 */
585 va_start (args, msg);
586 vfprintf (stderr, MsgBuff, args);
587 va_end (args);
588
589 /*
590 ** Flush standard error output
591 */
592 fsync (fileno (stderr));
593
594 return;
595
596}
597#endif
Note: See TracBrowser for help on using the repository browser.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette