/************************************************************************ ** * ** COPYRIGHT (c) DIGITAL EQUIPMENT CORPORATION, 1993 * ** ALL RIGHTS RESERVED. UNPUBLISHED - RIGHTS RESERVED * ** UNDER THE COPYRIGHT LAWS OF THE UNITED STATES. * ** * ** RESTRICTED RIGHTS LEGEND: USE, DUPLICATION, OR DISCLOSURE * ** BY THE U.S. GOVERNMENT IS SUBJECT TO RESTRICTIONS AS SET * ** FORTH IN SUBPARAGRAPH (C)(1)(II) OF DFARS 252.227-7013, * ** OR IN FAR 52.227-19, OR IN FAR 52.227-14 ALT. III, AS * ** APPLICABLE. * ** * ** THIS SOFTWARE IS PROPRIETARY TO AND EMBODIES CONFIDENTIAL * ** TECHNOLOGY OF DIGITAL. POSSESSION, USE, OR COPYING OF THE * ** SOFTWARE AND MEDIA IS AUTHORIZED ONLY PURSUANT TO A VALID * ** WRITTEN LICENSE FROM DIGITAL. * ** * ************************************************************************* **++ ** ** FACILITY: ** ** X.29 Destination Example Program ** ** ABSTRACT: ** ** Digital is furnishing this example software "as is" without ** warranty of any kind, express or implied, including the implied ** warranties of merchantability and fitness for a particular purpose. ** Digital disclaims any and all liability for the performance or ** non-performance of this software. ** ** ** This program is a simple example of an X.29 destination that ** asks the X.29 user for a password before allowing them to log in. ** ** The following NCL commands can be used to configure X.25. This ** configeration assumes the following ** - the estination example is started by a application entity ** - the file specified by the application entity contains a DCL ** command to run the destination executable. ** ** ** create x25 access ** create x25 client ** ! ** ! Create DTE classes ** ! ** create x25 access dte class crock type remote ** set x25 access dte class crock service node {(node=dundee, - ** rating=512)} ** create x25 access dte class crock1 type remote ** set x25 access dte class crock1 service node {(node=dundee, - ** rating=512)} ** ! ** ! Create security DTE class ** ! ** create x25 access security dte class default ** ! ** ! Create remote DTE entity ** ! ** create x25 access security dte class default remote dte match_all - ** remote address prefix * ** set x25 access security dte class default remote dte match_all - ** rights identifier {match_all} ** ! ** ! Create template ** ! ** create x25 access template net_template1 ** set x25 access template net_template1 dte class crock ** create x25 access template default ** ! ** ! Create filter ** ! ** create x25 access filter receive ** set x25 access filter receive incoming dte address 12345 ** ! ** ! Create security filter ** ! ** create x25 access security filter default ** set x25 access security filter default acl - ** {(identifier=(match_all),access=all)} ** ! ** ! Create application entity ** ! ** create x25 access application receive ** set x25 access application receive filters {receive} ** set x25 access application receive type x29 ** set x25 access application receive user system ** set x25 access application receive file sys$system:x25$destination.com ** ! ** ! Enable everything ** ! ** enable x25 access ** enable x25 client ** enable x25 access application receive ** ** ** FUNCTIONAL DESCRIPTION: ** ** * Include external macro and constant definitions ** and define local macros and constants ** * Declare structures for mailbox, FAO, NW and NV descriptors & IOSB ** * Assign a channel to NW ** * Assign a channel to mailbox ** * Read mailbox to obtain nv_unit and convert it to a device ** name string ** * Assign a channel to NV ** * Output a welcome message ** * Determine local echo mode from terminal characteristics ** if local echo mode make sure PAD echo parameter is turned off ** * Read the password from the terminal and validate it ** * If password was correct then clear the typeahead characteristics ** and set the temp nohang bit else deaccess NW ** * Deassign NV so that login will start on NV unit ** * Deassign channels to NW and mailbox ** **-- **/ /* * Included macros and definitions */ #include /* Standard C i/o */ #include /* System services */ #include /* Terminal characteristics */ #include /* Terminal characteristics */ #include /* Calling std. descriptors */ #include /* i/o definitions */ #include /* P.S.I. constants */ #include /* sys$... function prototypes */ #include /* strcmp prototype */ #include /* * Local macros and definitions */ #define check_status(x) if (!((x) &1)) sys$exit(x) /* Error handler */ #define UBYTE char #define UWORD unsigned short #define ULONG unsigned int /* * Entry point */ main() { /* * Local storage */ UWORD nv_chan; UWORD nw_chan; UWORD mbx_chan; ULONG status; ULONG nv_unit; ULONG temp_nohang_on = 1; ULONG term_char[4]; char term_rcv_buff[40]; char welcome_msg[49] = "Welcome to the X.29 Example Program\r\n"; char pwd_prmpt[16] = "X.29 Password: "; char password[6] = "STEVE"; char nv_name_buf[40]; static struct mailbox { UWORD msgtype; UWORD unit; UBYTE count1; UBYTE name[15]; UBYTE count2; UBYTE info[491]; } mailbox; static struct nv_name { ULONG length; ULONG address; } nv_name; static struct pad_param_block { ULONG param_num; ULONG param_val; } pad_param_block = { psi$k_x29_par_echo, 0 }; ULONG pad_param_len = sizeof(pad_param_block); int pad_echo; /* * Descriptors */ static $DESCRIPTOR(mbx_name, "SYS$NET"); static $DESCRIPTOR(nw_name, "_NWA0:"); static $DESCRIPTOR(fao_control, "!AC!UW"); /* * IO Status block definition */ volatile struct { UWORD status; /* Final io status */ UWORD dlen; /* Usually data length */ ULONG iosb_1; /* Device dependent */ } io_status; /* * Initialise nv_name */ nv_name.length = sizeof(nv_name_buf); nv_name.address = (unsigned int)nv_name_buf; /* * Assign a channel to NW */ status = sys$assign( &nw_name, /* devnam */ &nw_chan, /* chan */ 0, /* acmode */ 0 ); /* mbxnam */ check_status(status); /* * Assign a channel to mailbox */ status = sys$assign( &mbx_name, /* devnam */ &mbx_chan, /* chan */ 0, /* acmode */ 0 ); /* mbxnam */ check_status(status); /* * Read mailbox message to get connect message */ status = sys$qiow( 0, /* efn */ mbx_chan, /* chan */ IO$_READVBLK, /* func */ &io_status, /* iosb */ 0, /* astadr */ 0, /* astprm */ &mailbox, /* p1 */ sizeof(mailbox), /* p2 */ 0, /* p3 */ 0, /* p4 */ 0, /* p5 */ 0 ); /* p6 */ check_status(status); check_status(io_status.status); nv_unit = mailbox.unit; /* * Convert unit number to device name string */ status = sys$fao( &fao_control, /* ctrstr */ &nv_name, /* outlen */ &nv_name, /* outbuf */ &mailbox.count1, /* p1 */ nv_unit ); /* p2 */ check_status(status); /* * Assign a channel to NV */ status = sys$assign( &nv_name, /* devnam */ &nv_chan, /* chan */ 0, /* acmode */ 0 ); /* mbxnam */ check_status(status); /* * Output welcome message */ status = sys$qiow( 0, /* efn */ nv_chan, /* chan */ IO$_WRITEVBLK, /* func */ &io_status, /* iosb */ 0, /* astadr */ 0, /* astprm */ &welcome_msg, /* p1 */ sizeof(welcome_msg),/* p2 */ 0, /* p3 */ 0, /* p4 */ 0, /* p5 */ 0 ); /* p6 */ check_status(status); check_status(io_status.status); /* * Read the PAD's echo parameter. */ status = sys$qiow( 0, /* efn */ nw_chan, /* chan */ IO$_NETCONTROL, /* func */ &io_status, /* iosb */ 0, /* astadr */ 0, /* astprm */ &pad_param_block, /* p1 */ pad_param_len, /* p2 */ psi$k_x29_pad_params, /* p3 */ psi$k_x29_read_specific, /* p4 */ 0, /* p5 */ nv_unit ); /* p6 */ check_status(status); check_status(io_status.status); /* * If the PAD is set to echo, then turn it off. */ pad_echo = pad_param_block.param_val; if( pad_echo ) { pad_param_block.param_num = psi$k_x29_par_echo, pad_param_block.param_val = 0; status = sys$qiow( 0, /* efn */ nw_chan, /* chan */ IO$_NETCONTROL, /* func */ &io_status, /* iosb */ 0, /* astadr */ 0, /* astprm */ &pad_param_block, /* p1 */ pad_param_len, /* p2 */ psi$k_x29_pad_params, /* p3 */ psi$k_x29_set, /* p4 */ 0, /* p5 */ nv_unit ); /* p6 */ check_status(status); check_status(io_status.status); }; /* * Read password from the terminal */ status = sys$qiow( 0, /* efn */ nv_chan, /* chan */ IO$_READPROMPT | IO$M_NOECHO | IO$M_CVTLOW, /* func */ &io_status, /* iosb */ 0, /* astadr */ 0, /* astprm */ &term_rcv_buff, /* p1 */ sizeof(term_rcv_buff), /* p2 */ 0, /* p3 */ 0, /* p4 */ pwd_prmpt, /* p5 */ sizeof(pwd_prmpt) ); /* p6 */ check_status(status); check_status(io_status.status); term_rcv_buff[io_status.dlen] = '\0'; /* * Set PAD echo back to what it was originally. */ if( pad_echo ) { pad_param_block.param_num = psi$k_x29_par_echo, pad_param_block.param_val = 1; status = sys$qiow( 0, /* efn */ nw_chan, /* chan */ IO$_NETCONTROL, /* func */ &io_status, /* iosb */ 0, /* astadr */ 0, /* astprm */ &pad_param_block, /* p1 */ pad_param_len, /* p2 */ psi$k_x29_pad_params, /* p3 */ psi$k_x29_set, /* p4 */ 0, /* p5 */ nv_unit ); /* p6 */ check_status(status); check_status(io_status.status); }; /* * Validate the password * * This code could be much more complex (looking up a coded form * in a file, for example) */ if ( !strcmp(password,term_rcv_buff) ) { /* * Clear the notypeahead characteristics * Note that this requires PHY_IO privilege */ status = sys$qiow( 0, /* efn */ nv_chan, /* chan */ IO$_SENSECHAR, /* func */ &io_status, /* iosb */ 0, /* astadr */ 0, /* astprm */ &term_char, /* p1 */ sizeof(term_char), /* p2 */ 0, /* p3 */ 0, /* p4 */ 0, /* p5 */ 0 ); /* p6 */ check_status(status); check_status(io_status.status); term_char[1] = (TT$M_NOTYPEAHD ^ 0xffffffff) & term_char[1]; status = sys$qiow( 0, /* efn */ nv_chan, /* chan */ IO$_SETCHAR, /* func */ &io_status, /* iosb */ 0, /* astadr */ 0, /* astprm */ &term_char, /* p1 */ sizeof(term_char), /* p2 */ &io_status.dlen, /* p3 */ &io_status.iosb_1, /* p4 */ 0, /* p5 */ 0 ); /* p6 */ check_status(status); check_status(io_status.status); /* * Password was correct so set the temp nohang bit * to enable log in */ status = sys$qiow( 0, /* efn */ nw_chan, /* chan */ IO$_NETCONTROL, /* func */ &io_status, /* iosb */ 0, /* astadr */ 0, /* astprm */ &temp_nohang_on, /* p1 */ 4, /* p2 */ psi$k_x29_temp_nohang, /* p3 */ psi$k_x29_set, /* p4 */ 0, /* p5 */ nv_unit ); /* p6 */ check_status(status); check_status(io_status.status); } else { /* * Password was incorrect so clear the call */ status = sys$qiow( 0, /* efn */ nw_chan, /* chan */ IO$_DEACCESS, /* func */ &io_status, /* iosb */ 0, /* astadr */ 0, /* astprm */ 0, /* p1 */ 0, /* p2 */ 0, /* p3 */ 0, /* p4 */ 0, /* p5 */ nv_unit ); /* p6 */ check_status(status); check_status(io_status.status); /* * When the NV channel is deassigned the NV unit * will disappear */ } /* * Deassign NV channel */ status = sys$dassgn( nv_chan ); /* chan */ check_status(status); /* * Deassign NW channel */ status = sys$dassgn( nw_chan ); /* chan */ check_status(status); /* * Deassign mailbox channel */ status = sys$dassgn( mbx_chan ); /* chan */ check_status(status); /* * Exit with good status */ sys$exit(SS$_NORMAL); }