#pragma module URL_SND "URL-SND-1-A" /* **++ ** FACILITY: Remote URL Activator ** ** MODULE DESCRIPTION: ** ** This is a VMS-part of the "remote UTL activator", contains a code to send ** packet to remote PC with running "URL-Executor". ** ** AUTHOR: Ruslan R. Laishev ** Copyright 2009, Ruslan R. Laishev ** ** This program can be built by the following procedure: ** ** $ CC/NOWARN/NODEBUG/INCL=[] URL-SND.C,MD5.C ** $ LINK/NODEBUG/NOTRACE URL-SND,MD5 ** ** ** Control logicals: ** DEFINE/SYS/EXEC URL_SND_SHARED "trhdfh#$%gvbv" - a shared secret ** DEFINE/SYS/EXEC URL_SND_PORT 8133 - default UDP port ** ** C Binding: ** status = url_snd(); ** ** ** MODIFICATION HISTORY: ** ** 7-JUL-2009 RRL Initial coding. ** 8-JUL-2009 RRL Added some code to get "Remote Port Info" under HP TCP/IP **-- */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #define __NEW_STARLET 1 #include #define INIT_SDESC(dsc, len, ptr) {(dsc).dsc$b_dtype = DSC$K_DTYPE_T;\ (dsc).dsc$b_class = DSC$K_CLASS_S; (dsc).dsc$w_length = (short) (len);\ (dsc).dsc$a_pointer = (char *) (ptr);} #define INIT_DDESC(dsc) {(dsc).dsc$b_dtype = DSC$K_DTYPE_T;\ (dsc).dsc$b_class = DSC$K_CLASS_D;(dsc).dsc$w_length = 0;\ (dsc).dsc$a_pointer = NULL;} $DESCRIPTOR(dsc_ucxdev, "UCX$DEVICE"); $DESCRIPTOR(dsc_tcpipdev, "TCPIP$DEVICE"); $DESCRIPTOR(dsc_port, "URL_SND_PORT"); $DESCRIPTOR(dsc_secret, "URL_SND_SHARED"); $DESCRIPTOR(dsc_url, "URL_SND_URL"); $DESCRIPTOR(dsc_node, "URL_SND_NODE"); $DESCRIPTOR(dsc_stbl, "LNM$SYSTEM_TABLE"); $DESCRIPTOR(dsc_ptbl, "LNM$PROCESS_TABLE"); #define URL_SND_PORT 8133 /* ** ** MACRO DEFINITIONS ** */ #define min(x,y) ((x > y)?y:x) #define max(x,y) ((x < y)?y:x) const struct { short proto; char type; char domain; } sck_parm = {INET$C_UDP,INET_PROTYP$C_DGRAM,INET$C_AF_INET}; #pragma member_alignment save #pragma nomember_alignment struct pdu { unsigned short len; unsigned char hash[16], url[1]; }; #pragma member_alignment restore /* **++ ** FUNCTIONAL DESCRIPTION: ** ** Performs an authentication and authorization of the PMAS user against ** remote RADIUS server/database. ** ** FORMAL PARAMETERS: ** ** email_d: E-Mail entered by user AS IS, by descriptor ** password_d: Password string, by descriptor ** ** RETURN VALUE: ** ** VMS Condition code. ** **-- */ int url_snd (void) { int status,len,ipaddr,reqidt = 0; unsigned char obuf [1024],ibuf[1024],secret[64],hash[64]; unsigned short buflen,secretlen,port,hostlen = 0; static short chan; const struct sockaddr_in sock_host = {INET$C_AF_INET,0,INET$C_INADDR_ANY,0}; ILE2 loc_host = {sizeof(struct sockaddr_in),0,&sock_host}; ILE3 rem_host = {sizeof(struct sockaddr_in),0,&sock_host,&hostlen}, lnms[] = {{sizeof(ibuf),LNM$_STRING,ibuf,&buflen},{0,0,0,0}}; iosb netiosb; struct pdu *ptr = (struct pdu *)obuf; MD5_CTX md5; struct hostent *hp; /* ** Get parameters from logicals */ if ( !(1 & (status = sys$trnlnm (0,&dsc_stbl,&dsc_port,&PSL$C_EXEC,&lnms))) ) port = URL_SND_PORT; else if ( !lib$cvt_dtb(buflen,ibuf,&port) ) return SS$_INSFARG; if ( !(1 & (status = sys$trnlnm (0,&dsc_stbl,&dsc_secret,&PSL$C_EXEC,&lnms))) ) return status; memcpy(secret,ibuf,buflen); secretlen = buflen; /* ** Initialize network stuff */ if ( !(1 & (status = sys$assign( &dsc_ucxdev,&chan,0,0))) ) { if ( status != SS$_NOSUCHDEV ) return status; if ( !(1 & (status = sys$assign( &dsc_tcpipdev,&chan,0,0))) ) return status; } /* ** Create a UDP device */ sock_host.sin_family = INET$C_AF_INET; status = sys$qiow (EFN$C_ENF,chan,IO$_SETMODE,&netiosb, 0,0,&sck_parm,0,&loc_host,0,0,0); if ( !(status & 1) ) { sys$dassgn (chan); return status; } if ( !(netiosb.iosb$w_status & 1) ) { sys$dassgn (chan); return netiosb.iosb$w_status; } /* ** Get target node IP-address from the logical name */ if ( !(1 & (status = sys$trnlnm (0,&dsc_ptbl,&dsc_node,0,&lnms))) ) return status; ibuf[buflen] = '\0'; if ( -1 != (status = inet_addr(ibuf)) ) sock_host.sin_addr.s_addr = inet_addr(ibuf); else if ( hp = gethostbyname(ibuf) ) sock_host.sin_addr.s_addr = *(int *)hp->h_addr; sock_host.sin_port = htons(port); /* ** Retrive an URL to sent to target node */ if ( !(1 & (status = sys$trnlnm (0,&dsc_ptbl,&dsc_url,0,&lnms))) ) return status; /* ** Prepare REQUEST packet */ len = ptr->len = min(256,buflen); memcpy(&ptr->url,ibuf,ptr->len); memset(&ptr->hash,0,sizeof(ptr->hash)); MD5Init(&md5); MD5Update(&md5,&ptr->url,ptr->len); MD5Update(&md5,&secret,secretlen); MD5Final(&ptr->hash,&md5); len += sizeof(ptr->hash) + sizeof(ptr->len); ptr->len = (unsigned short) htons(ptr->len); /* ** Queue the read request */ if ( !(1 & (status = sys$qiow (EFN$C_ENF,chan,IO$_WRITEVBLK,&netiosb,0,0, &obuf,len,&rem_host,0,0,0))) ) sys$dassgn (chan); return (1 & status)?netiosb.iosb$w_status:status; } #if 1 int main (void) { int status; status = url_snd(); return status; } #endif