#pragma module BBS_WASD "BBS_WASD-2-G" /* **++ ** FACILITY: BBS (Forum) ** ** MODULE DESCRIPTION: ** ** This module is supposed to be called from BBS.COM/BBS.SHTML, ** to performs a send SMS action. ** ** AUTHORS: ** ** Ruslan R. Laishev ** ** CREATION DATE: 10-APR-2008 ** ** DESIGN ISSUES: ** ** This module use a WASD CGIplus technology. List of Environment/Form element/variables: ** ** ** ** ** MODIFICATION HISTORY: ** ** ** {@tbs@}... **-- */ /* ** ** INCLUDE FILES ** */ #include #include #include #include #include #include #include #include #include #include #include #include #include #define __NEW_STARLET 1 #include #include "cgilib.h" #include "bbsdef.h" #include "bbs_sql.h" #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 = (ptr);} int DebugWatch = 0; #define true 1 #define false 0 unsigned char bbs_rand [128]; unsigned short bbs_randl = 0; /* ** A Template for results of processing requests */ $DESCRIPTOR (bbs_start, ""); $DESCRIPTOR (bbs_condition, "!/"); $DESCRIPTOR (bbs_end, ""); static void bbs_out ( struct dsc$descriptor_s *fmt, ... ) { int status,argc,argl[32]; char buf[8192]; struct dsc$descriptor buf_dsc; va_list ap; memset(argl,0,sizeof(argl)); va_start(ap,fmt); va_count(argc); argc--; for (int i = 0;(i < argc) && (i < sizeof(argl)/sizeof(argl[0]));i++) argl[i] = va_arg(ap,unsigned); va_end(ap); if ( argc ) { INIT_SDESC(buf_dsc,sizeof(buf),buf); if ( !(1 & (status = sys$faol(fmt,&buf_dsc.dsc$w_length,&buf_dsc,argl))) ) lib$signal(status); lib$put_output(&buf_dsc); } else lib$put_output(fmt); } static int bbs_user_show ( BBS__USER *uctx ) { int status,uic = 0; char *cp; /* ** */ if ( cp = CgiLibVar ("WWW_FORM_UIC") ) uic = atoi(cp); /* ** */ if ( !uic ) status = rdb_uat_list(uctx); else status = rdb_uat_show(uctx,uic); if ( !(1 & status ) ) CgiLibResponseError (__FILE__, __LINE__, 0, "bbs_uat_show:status=%d",status); return status; } static int bbs_user_login ( BBS__USER *uctx ) { int status,sqlcode; SHA_CTX sha1; ROW_UAT uat; char *_name,*_pass; memset(uctx,0,sizeof(BBS__USER)); /* ** */ if ( !(_name = CgiLibVar ("WWW_FORM_USER")) || !(_pass = CgiLibVar ("WWW_FORM_PASS")) ) return SS$_INVLOGIN; /* ** Find &Retrieve from RDB DB user's record */ UAT_LOGIN(&sqlcode,_name,_pass,&uat); if ( sqlcode ) sql_signal(); /* ** */ if ( !uat.uat$l_uic ) return SS$_NOSUCHUSER; /* ** Form new BBS__USER context */ uctx->bbs_l_uic = uat.uat$l_uic; uctx->bbs_l_privs = uat.uat$l_privs; uctx->bbs_l_flags = uat.uat$l_flags; /* ** */ SHA1_Init(&sha1); SHA1_Update(&sha1,uctx,sizeof(BBS__USER)); SHA1_Update(&sha1,bbs_rand,bbs_randl); SHA1_Final(&uctx->bbs_r_md,&sha1); return SS$_NORMAL; } static int bbs_user_check ( BBS__USER *uctx, char *cookie ) { int status; SHA_CTX sha1; BBS__USER ctx; char smd[SHA_DIGEST_LENGTH*2]; /* ** Form new BBS__USER context */ memset(uctx,0,sizeof(BBS__USER)); memset(&ctx,0,sizeof(BBS__USER)); /* ** BBS__USER=1:00000000:00000000:000000003E7DAD01FFFFFFFFD30BF3754D800043 */ if ( 4 != sscanf(cookie+10,"%x:%x:%x:%40s",&status,&ctx.bbs_l_privs,&ctx.bbs_l_flags,smd) ) return SS$_NORMAL; ctx.bbs_l_uic = status; _ahex2bin(&smd,SHA_DIGEST_LENGTH*2,&ctx.bbs_r_md); *uctx = ctx; memset(&ctx.bbs_r_md,0,SHA_DIGEST_LENGTH); /* ** Compute a SHA1 */ SHA1_Init(&sha1); SHA1_Update(&sha1,&ctx,sizeof(BBS__USER)); SHA1_Update(&sha1,bbs_rand,bbs_randl); SHA1_Final(&ctx.bbs_r_md,&sha1); /* ** Compare digest */ if ( memcmp(&ctx.bbs_r_md,&uctx->bbs_r_md,sizeof(ctx.bbs_r_md)) ) { memset(uctx,0,sizeof(BBS__USER)); return SS$_INVLOGIN; } return SS$_NORMAL; } static int bbs_cat_list ( BBS__USER *uctx ) { return rdb_cat_list(uctx); } static int actrtn_topic_show ( BBS__USER *uctx ) { int status,subcat = 0,topic = 0; char *cp; /* ** */ if ( cp = CgiLibVar ("WWW_FORM_SUBCAT") ) subcat = atoi(cp); if ( cp = CgiLibVar ("WWW_FORM_TOPIC") ) topic = atoi(cp); /* ** */ status = rdb_topic_list(uctx,subcat); /* if ( !topic) status = rdb_topic_list(uctx,subcat); else status = rdb_topic_show(uctx,subcat,topic); */ return status; } /* **++ ** FUNCTIONAL DESCRIPTION: ** ** A top level procedure of processing request. ** ** FORMAL PARAMETERS: ** ** None. ** ** RETURN VALUE: ** ** None. ** ** SIDE EFFECTS: ** ** All diagnostic and results is returned to the current I/O stream (i.e to the HTTP server), ** this routine can force process exit if some inconsistence is occured. ** **-- */ #define ASCIC(a) ((unsigned char)sizeof(a)-1),a ACTRTN actrtn_tbl [] = { {ASCIC("uat$login"), bbs_user_login}, {ASCIC("uat$reg"), NULL}, {ASCIC("uat$mod"), NULL}, {ASCIC("uat$del"), NULL}, {ASCIC("uat$show"), bbs_user_show}, {ASCIC("uat$logoff"), NULL}, {ASCIC("cat$list"), bbs_cat_list}, {ASCIC("topic$show"), actrtn_topic_show}, }; $DESCRIPTOR (html_dsc, "Content-type: text/html\ncharset=ISO-8859-5\n\n\ \n\ \n\ \n"); void Dispatcher (void) { int status,PostBufferCount = 0; char *PostBufferPtr,*src,*rtn,smd[SHA_DIGEST_LENGTH*2]; BBS__USER uctx; int (*rtnptr) (BBS__USER *); /* ** Get a request body */ CgiLibReadRequestBody (&PostBufferPtr, &PostBufferCount); CgiLibFormRequestBody (PostBufferPtr, PostBufferCount); /* if ( !PostBufferPtr || !PostBufferCount ) { CgiLibResponseError (__FILE__, __LINE__, 0, "No body in the POST!"); return; } */ free (PostBufferPtr); if ( DebugWatch ) while ( src = CgiLibVarNull ("*") ) fprintf (stdout, "|%s|\n", src); lib$put_output(&html_dsc); /* ** Get & from user's context */ memset(&uctx,0,sizeof(BBS__USER)); if ( src = CgiLibVar("WWW_HTTP_COOKIE") ) { /* ** Validate the vector wich has been gotten from a remote user */ status = bbs_user_check(&uctx,src); } /* ** URI is expect in form : ** /bbs?=&=[&=]... ** /bbs?rtn=uat-show&uic=1 ** Get an action code, routine code ** Lookup action/routine table with given arguments */ src = CgiLibVar ("WWW_REMOTE_ADDR"); if ( !(rtn = CgiLibVar ("WWW_FORM_RTN")) ) return CgiLibResponseError (__FILE__, __LINE__, 0, "No Action-Routine in the request!"); for (int i = 0;i < sizeof(actrtn_tbl)/sizeof(actrtn_tbl[0]);i++) if ( !strncasecmp(rtn,actrtn_tbl[i].rtn_t_name,actrtn_tbl[i].rtn_b_len) && actrtn_tbl[i].rtn ) { rtnptr = actrtn_tbl[i].rtn; status = rtnptr(&uctx); _bin2ahex(&uctx.bbs_r_md,SHA_DIGEST_LENGTH,smd); return bbs_out(&bbs_condition,uctx.bbs_l_uic,uctx.bbs_l_privs,uctx.bbs_l_flags, SHA_DIGEST_LENGTH*2,smd, status,$VMS_STATUS_SEVERITY(status),0,0,&actrtn_tbl[i].name); } /* ** An action routine has not been found the dispatch table ** write an error message and return to main loop. */ CgiLibResponseError (__FILE__, __LINE__, 0, "Unrecognized Action-Routine in the request!"); } /* **++ ** FUNCTIONAL DESCRIPTION: ** ** The main start procedure, perform a CGIplus specific initialization. ** ** DESIGN: ** A behaviour of this script is controled by logical BBS$WATCH. A VMS ** user run this script must be authorized by PrePaid Card Administrator. ** **-- */ int main (void) { int status,IsCgiPlus = 0; char *cp; /* ** CGIPlus Initialization */ DebugWatch = (NULL != getenv ("BBS$WATCH")); CgiLibEnvironmentSetDebug (DebugWatch); CgiLibEnvironmentInit (0, NULL, false); IsCgiPlus = CgiLibEnvironmentIsCgiPlus (); if ( !(cp = getenv("BBS$RAND")) ) return SS$_INSFARG; bbs_randl = strnlen(cp,sizeof(bbs_rand)); memcpy(bbs_rand,cp,bbs_randl); /* ** Initialize libraries of HTML Templates & Help Texts */ if ( !(1 & (status = bbs_hxlb_init())) ) lib$signal(status); /* ** Main processing block/loop */ // do { /* ** with CGIplus this call will block waiting for the next request */ CgiLibVar (""); Dispatcher(); if ( IsCgiPlus ) CgiLibCgiPlusEOF (); // } while ( IsCgiPlus ); }