26 function GetUserRec($p_dbh, $cu, $username) {
27 if (preg_match(
"/\D/", $username)) {
28 # username contains non-digits 29 $qby =
'user_alias ilike ';
31 $qby =
'user_name = ';
34 $return_ary = array();
36 $sqluser =
"SELECT trim(cuuser.user_name) as user_name, trim(cuuser.passwd) as passwd, 37 forcechange as fchange, coalesce(forceremain,0) as fremain, failedremain, pwchange as pchange, 38 trim(email) as email, confidence, 39 lastlogin as llog, failedlogin as flog, coalesce(msg_tx,0) as msg_tx, userflags & " . GetUserFlagsValue(
'MEM_FORCE_RESET') .
"::int4 as freset, 40 userflags, coalesce(challenge_quest_id,0) as savecqid, 41 coalesce(cuadmin.flagset,0) as flagset, coalesce(cuadmin.flagset2,0) as flagset2, coalesce(cuadmin.flagset3,0) as flagset3, 42 cuadmin.livewait, trim(cuadmin.lastupdate) as lastupdate, cuadmin.min_chlng_qst as min_chlng_qst, 43 cuadmin.pname, coalesce(histdays,0) as fhdays, coalesce(gracelimit,0) as grace, trmemomaxlen, trim(cuadmin.cu) as cu 44 FROM cuusers as cuuser 45 JOIN cuadmin on cuadmin.cu = '" . prep_save($cu) .
"' 46 WHERE cuuser.cu='$cu' and cuuser.$qby '" . prep_save(strtolower($username)) .
"' ";
48 $mbr_sth = db_query($sqluser, $p_dbh);
49 if (db_num_rows($mbr_sth) == 1) {
50 $return_ary = db_fetch_assoc($mbr_sth,0);
51 $return_ary[
'rowfound'] = 1;
53 # set these with some other query instead... 54 $return_ary[
'mfaquest'] = GetMammothMFA($p_dbh, $cu, $return_ary[
'user_name'], $return_ary[
'savecqid'], $return_ary[
'pchange']);
55 $mbrMfaQuest = HCU_MFADecode(HCU_JsonDecode($return_ary[
'mfaquest']));
56 $return_ary[
'chcount'] = $mbrMfaQuest[
'mfacount'];
57 $return_ary[
'mfadate'] = $mbrMfaQuest[
'mfadate'];
59 if ($return_ary[
'fchange'] ==
'Y') {
60 $FORCEUPDATE += 1; #password
63 if (($return_ary[
'msg_tx'] & GetMsgTxValue(
'MSGTX_FORCE_EM')) || $return_ary[
'email'] ==
'') {
64 $FORCEUPDATE += 2; # email
66 if (intval($return_ary[
'flagset3'] & GetFlagsetValue(
'CU3_MFA_AUTHCODE')) == 0 &&
67 ( $return_ary[
'freset'] == GetUserFlagsValue(
'MEM_FORCE_RESET') || $return_ary[
'chcount'] < $return_ary[
'min_chlng_qst'])
69 $FORCEUPDATE += 4; #challenge questions
71 if (($return_ary[
'flagset2'] & GetFlagsetValue(
'CU2_ALIAS_REQ')) && !Check_Member_UseAlias($return_ary[
'user_name'])) {
78 $return_ary[
'forceupdate'] = $FORCEUPDATE;
81 if ($return_ary[
'failedremain'] <= 0 || ( ($return_ary[
'forceupdate'] & 29) > 0 && $return_ary[
'fremain'] <= 0 )) {
83 $return_ary[
'lockedacct'] = 1;
85 $return_ary[
'lockedacct'] = 0;
89 $return_ary[
'rowfound'] = 0;
90 $return_ary[
'sql'] = $sqluser;
97 function MakeUserkey($CU, $MEMBER) {
99 $appexpires = time() + 900; # 15 minutes
100 $apphash = MD5($privkey . MD5(join(
':', array($privkey, $appexpires, $CU, $MEMBER, $MEMBER))));
102 $apptoken = urlencode(
"H=$apphash&E=$appexpires&A=$MEMBER");
116 function MakeV94key($CU, $MEMBER, $TTL, $KEY, $HMETHOD, $PWCHANGE=0) {
117 $appexpires = time() + $TTL; # 94 days
118 if ($HMETHOD ==
'S') {
119 $apphash = hash_hmac(
'sha384',MD5(join(
':', array($KEY, $appexpires, $CU, $MEMBER, $PWCHANGE))),$KEY);
120 $apptoken = urlencode(
"H=$apphash&E=$appexpires&A=$MEMBER&P=$PWCHANGE");
122 $apphash = MD5($KEY . MD5(join(
':', array($KEY, $appexpires, $CU, $MEMBER, $MEMBER))));
123 $apptoken = urlencode(
"H=$apphash&E=$appexpires&A=$MEMBER&C=$MEMBER");
141 function MakeV94Dkey($CU, $MEMBER, $userrec, $TTL, $KEY, $HMETHOD) {
142 $appexpires = time() + $TTL; # 94 days
144 if ($HMETHOD ==
'S') {
145 # make device cookie string, use it as apptoken 'P' value 146 $mfaMode = (intval($userrec[
'flagset3'] & GetFlagsetValue(
'CU3_MFA_AUTHCODE')));
147 $mfaDate = (integer) HCU_array_key_value(
"mfadate", $userrec);
148 $passwd = HCU_array_key_value(
"passwd", $userrec);
149 $email = HCU_array_key_value(
"email", $userrec);
150 $confidence = HCU_array_key_value(
"confidence", $userrec);
152 $deviceToken = hash_hmac(
'sha384',GetDeviceCookieContentString(),trim($passwd) . trim(strtolower($email)) . trim(strtolower($confidence)) . $mfaMode . $mfaDate);
153 $apphash = hash_hmac(
'sha384',MD5(join(
':', array($KEY, $appexpires, $CU, $MEMBER, $deviceToken))),$KEY);
154 $apptoken = urlencode(
"H=$apphash&E=$appexpires&A=$MEMBER&P=$deviceToken");
156 $apphash = MD5($KEY . MD5(join(
':', array($KEY, $appexpires, $CU, $MEMBER, $MEMBER))));
157 $apptoken = urlencode(
"H=$apphash&E=$appexpires&A=$MEMBER&C=$MEMBER");
162 function CheckUserkey($CU, $USERKEY, $apptokenkey) {
165 $result = array(
'Status' => array(
'Code' =>0,
'Message' =>
'Success'));
167 $apptokarr = array();
168 parse_str(urldecode($USERKEY), $apptokarr);
170 if ($apptokarr[
'E'] < time()) {
171 throw new Exception(
"Invalid Credentials (Expired Token) " . __LINE__,15510);
174 if (is_null($apptokarr[
'E']) || is_null($apptokarr[
'A']) || is_null($apptokarr[
'H'])) {
175 throw new Exception(
"Invalid Credentials (Partial Token) " . __LINE__,15510);
177 # if no C= value, assume oldstyle userkey 178 # and set member as A= value so hash works 179 # for odyssey A & C are swapped 180 # A is Uid, C is primary account 182 if (is_null($apptokarr[
'C'])) {
183 $CAUTH = $apptokarr[
'A'];
185 $CAUTH = $apptokarr[
'C'];
187 $MEMBER = $apptokarr[
'A'];
188 $EXPIRES = $apptokarr[
'E'];
189 $hash = MD5($apptokenkey .
190 MD5(join(
':', array($apptokenkey, $EXPIRES, $CU, $MEMBER, $CAUTH))));
191 if ($apptokarr[
'H'] != $hash) {
192 throw new Exception(
"Invalid Credentials (Corrupted Token) " . json_encode($apptokarr) . __LINE__,15510);
194 }
catch (Exception $e) {
195 $result = array(
'Status' => array(
'Code' => $e->getCode(),
'Message' =>
'Failed ' . $e->getMessage()));
200 function CheckV94key($CU, $USERKEY, $KEY, $HMETHOD) {
203 $result = array(
'Status' => array(
'Code' => 0,
'Message' =>
'Success'));
205 $apptokarr = array();
206 parse_str(urldecode($USERKEY), $apptokarr);
208 if (!HCU_array_key_value(
'E',$apptokarr) || !HCU_array_key_value(
'A',$apptokarr) || !HCU_array_key_value(
'H',$apptokarr) ) {
209 throw new Exception(
"Invalid Credentials (Partial Token) ", 15510);
212 if ($apptokarr[
'E'] < time()) {
213 throw new Exception(
"Invalid Credentials (Expired Token) ", 15510);
216 $MEMBER = $apptokarr[
'A'];
217 $EXPIRES = $apptokarr[
'E'];
219 if (HCU_array_key_exists(
'P',$apptokarr) ) {
220 $PWCHANGE = HCU_array_key_value(
'P',$apptokarr);
224 if ($HMETHOD ==
'S') {
225 $hash = hash_hmac(
'sha384', MD5(join(
':', array($KEY, $EXPIRES, $CU, $MEMBER, $PWCHANGE))), $KEY);
227 $hash = MD5($KEY . MD5(join(
':', array($KEY, $EXPIRES, $CU, $MEMBER, $MEMBER))));
229 if ($apptokarr[
'H'] != $hash) {
230 throw new Exception(
"Invalid Credentials (Corrupt Token) ", 15510);
233 $result[
'data'] = $apptokarr;
234 }
catch (Exception $e) {
235 $result = array(
'Status' => array(
'Code' => $e->getCode(),
'Message' =>
'Failed ' . $e->getMessage()));
357 function MakeMFAKey($HB_ENV) {
359 $mfaExpires = date(
"Ymd", time() + (94 * 86400)); # 94 days
361 $mbrMfaQuest = HCU_MFADecode(HCU_JsonDecode($HB_ENV[
'mfaquest']));
362 $mfaMode = (intval($HB_ENV[
'Fset3'] & GetFlagsetValue(
'CU3_MFA_AUTHCODE')));
365 $mfadate = HCU_array_key_exists(
"mfadate", $mbrMfaQuest) ? $mbrMfaQuest[
'mfadate'] :
"";
366 $MFAKey = hash_hmac(
'sha384',GetDeviceCookieContentString(),trim($HB_ENV[
'password']) . trim(strtolower($HB_ENV[
'savemail'])) . trim(strtolower($HB_ENV[
'confidence'])) . $mfaMode . $mfadate);
368 return "{$mfaExpires}{$MFAKey}";
371 function IsValidMFAKey($mfaKey, $userrec) {
372 $today = date(
"Ymd");
374 $mfaExpires = substr($mfaKey,0,8);
375 $mfaHash = substr($mfaKey,8);
377 $mfaMode = (intval($userrec[
'flagset3'] & GetFlagsetValue(
'CU3_MFA_AUTHCODE')));
378 $mfadate = HCU_array_key_exists(
"mfadate", $userrec) ? $userrec[
'mfadate'] :
"";
379 $cookiecontent = hash_hmac(
'sha384',GetDeviceCookieContentString(),trim($userrec[
'passwd']) . trim(strtolower($userrec[
'email'])) . trim(strtolower($userrec[
'confidence']))
380 . $mfaMode . $mfadate);
381 if ($cookiecontent == $mfaHash && $mfaExpires > $today) {
389 function PWD_prompt($dbh, $HB_ENV) {
390 $reply_arr = array(
'STATUS' => array(
'CODE' =>3000,
'SEVERITY' =>
'ERROR'),
391 'DTSERVER' => date(
'YmdHis') );
394 # 'forgot password' link 397 $reply_arr[
'MFA'][
'AUTHREQ'] =
'MFP';
398 $reply_arr[
'MFA'][
'MFABUNDLE'] = $HB_ENV[
'mfaBundle'];
400 $reply_arr[
'MFA'][
'PROMPT'] =
'Password';
401 $reply_arr[
'MFA'][
'CONFIDENCE'] = $HB_ENV[
'confidence'];
404 if ($HB_ENV[
'flagset'] & GetFlagsetValue(
'CU_MEMRESET') ){
405 $reply_arr[
'MFA'][
'FORGOTLINK'] = $HB_ENV[
'loginpath'] .
'/hcuResetPwd.prg?' . $HB_ENV[
'cuquery'];
407 $reply_arr[
'MFA'][
'FORGOTLABEL'] =
'Forgot your password';
413 function EML_prompt($dbh, $HB_ENV) {
414 $reply_arr = array(
'STATUS' => array(
'CODE' =>3000,
'SEVERITY' =>
'ERROR'),
415 'DTSERVER' => date(
'YmdHis') );
416 $reply_arr[
'MFA'][
'AUTHREQ'] =
'EML';
417 $reply_arr[
'MFA'][
'MFABUNDLE'] = $HB_ENV[
'mfaBundle'];
419 $reply_arr[
'MFA'][
'PROMPT'] =
'Confirm Email Address';
423 function checkBundle($mode, $mfaBundle, $inPost) {
427 # special case to check the bundle age 428 $built = HCU_array_key_value(
'BUILDTIME', $mfaBundle);
429 if ( empty($built) || (time() - $built) > 900 ) {
430 $returnBundle =
false;
432 $returnBundle =
true;
436 # previous mode is MFA, 437 # bundle contains USERID 440 if ( HCU_array_key_value(
'mode', $mfaBundle) !==
'MFA' ||
441 HCU_array_key_value(
'USERID',$mfaBundle) !== HCU_array_key_value(
'USERID',$inPost) ) {
442 $returnBundle =
false;
444 $returnBundle =
true;
448 # previous mode is EML 449 # bundle contains USERID, MFA_E 450 # Add MFQ completion marker 451 if ( HCU_array_key_value(
'mode', $mfaBundle) !==
'EML' ||
452 HCU_array_key_value(
'USERID',$mfaBundle) !== HCU_array_key_value(
'USERID',$inPost) ||
453 !HCU_array_key_exists(
'MFA_E',$mfaBundle) ) {
454 $returnBundle =
false;
456 $returnBundle =
true;
460 # previous mode is MFQ or EML or MFA 461 # bundle contains USERID, MFA_E, 462 # and either MFQ marker 464 !((HCU_array_key_value(
'mode', $mfaBundle) ===
'MFQ' && HCU_array_key_exists(
'haveMFQ',$mfaBundle)) ||
465 HCU_array_key_value(
'mode', $mfaBundle) ===
'EML' || HCU_array_key_value(
'mode', $mfaBundle) ===
'MFA')
466 || HCU_array_key_value(
'USERID',$mfaBundle) !== HCU_array_key_value(
'USERID',$inPost) ||
467 !HCU_array_key_exists(
'MFA_E',$mfaBundle)
469 $returnBundle =
false;
471 $returnBundle =
true;
475 # unexpected $mode - throw error 476 $returnBundle =
false;
479 return $returnBundle;
481 function createBundle($Cu, $mfaBundle) {
483 $mfaBundle = HCU_PayloadEncode($Cu,$mfaBundle);
484 $mfaBundle = str_replace(array(
"+",
"/",
"="), array(
"-",
"_",
"."), $mfaBundle);
485 }
catch (Exception $e) {
491 function openBundle($Cu, $mfaBundle) {
494 $mfaBundle = str_replace(array(
"-",
"_",
"."), array(
"+",
"/",
"="), $mfaBundle);
495 $mfaBundle = HCU_PayloadDecode($Cu, $mfaBundle);
497 }
catch (Exception $e) {
502 function GetMammothMFA($dbh, $CU, $MEMBER, $CQID, $PCHANGE) {
506 $retMfaArray = Array(
508 "answers" => Array(),
514 if (empty($CU) || empty($MEMBER)) {
515 throw new Exception(
"Missing CU or MEMBER");
518 $sql =
"SELECT cu, accountnumber, quest_id, answer " 519 .
"FROM cuquestselect WHERE cu = '$CU' " 520 .
"AND accountnumber = '$MEMBER'";
522 $sth = db_query($sql, $dbh);
524 while ($drow = db_fetch_array($sth,$row)) {
526 $retMfaArray[
'answers'][$drow[
'quest_id']] = $drow[
'answer'];
529 $retMfaArray[
'mfacount'] = count($retMfaArray[
'answers']);
530 $retMfaArray[
'challenge'] = (empty($CQID) ? 0 : $CQID);
531 $retMfaArray[
'mfadate'] = (empty($PCHANGE) ?
'' : strtotime($PCHANGE));
533 }
catch (Exception $e) {
535 $retMfaArray = Array(
537 "answers" => Array(),
544 return json_encode($retMfaArray);
546 function MFQ_defined($posted) {
547 # returns a count of MFA_* challenge question responses 548 # in (sanitized) array of posted values 550 foreach (array_keys($posted) as $rkey) {
551 $m = strpos($rkey,
'MFA_');
552 if ($m !== FALSE && $m == 0) {
567 function MFQ_response($HB_ENV, $inPost) {
569 $aryMfaQuest = HCU_JsonDecode($HB_ENV[
'mfaquest']);
570 $mbrMfaQuest = HCU_MFADecode($aryMfaQuest); # from the db
575 $dbcount = $mbrMfaQuest[
'mfacount']; # how many questions are in the db?
576 $mfapost = MFQ_resplist($inPost); #
get list of MFA variables in the posted request (skips MFA_E)
577 # update from mammoth - gets id and answers in array using Odyssey format 578 $mfacount = count($mfapost); # how many MFA_ responses (excluding MFA_E) did we
get?
580 if ($mfacount < $dbcount && ($HB_ENV[
'Fset2'] & GetFlagsetValue(
'CU2_RANDOM_CHAL')) == 0) {
581 # expected more challenge questions than we got, so fail 583 $failreason = GetUserFlagsValue(
'MEM_LOGIN_FAILED_QST');
584 throw new Exception(__LINE__ .
'MFA Failed m $mfacount d $dbcount',$failreason);# expected chall ques and got none
587 # make sure savemail is set in HB_ENV 588 # separate eMail check from challenge questions 589 # eMail check now using isValidEmail from cu_credentials 609 $aryMfaAnswers = $mbrMfaQuest[
'answers']; # stored answers
610 if (($HB_ENV[
'Fset2'] & GetFlagsetValue(
'CU2_RANDOM_CHAL'))) {
611 if ( $mbrMfaQuest[
'challenge'] > 0 ) {
613 $mfaAnswerIdx = Array($mbrMfaQuest[
'challenge']);
616 $mfaAnswerIdx = array_keys($mfapost);
620 $mfaAnswerIdx = array_keys($aryMfaAnswers);
624 # for each id in $mfaAnswerIdx 625 # intersect should be with posted answer set, not db answer set? 627 # 4/26/2018 added test to make sure there is some intersect 628 # between db list and list we will test, otherwise answering all 629 # the wrong questions still passes 632 # mfaAnswerIdx = ( if random, cqid if defined or posted ) else (not random, db ) 633 $aryToTest = array_intersect_key($aryMfaAnswers, array_flip($mfaAnswerIdx));
634 if (count($aryToTest) == 0 ) {
636 $failreason = GetUserFlagsValue(
'MEM_LOGIN_FAILED_QST');
637 throw new Exception(__LINE__ .
" MFA Failed Wrong Questions Answered",$failreason);# chall response mismatch
639 foreach ($aryToTest as $qid => $qanswer) {
640 if (strtolower(trim($qanswer)) != strtolower(trim(HCU_array_key_value(
"MFA_$qid",$inPost)))) {
642 $failreason = GetUserFlagsValue(
'MEM_LOGIN_FAILED_QST');
644 throw new Exception(__LINE__ .
" MFA $qid Failed",$failreason);# chall response mismatch
647 }
catch (Exception $e) {
648 # logging handled at point of call - nothing to do here but fall through? 649 # $failreason = $e->getMessage(); 651 return (array($fail, $failreason));
653 function MFQ_resplist($posted) {
654 # examines the (sanitized!) array of posted values 655 # returns list of MFA_ excluding MFA_E (email) 657 foreach (array_keys($posted) as $rkey) {
658 $m = strpos($rkey,
'MFA_');
659 if ($m !== FALSE && $m == 0 && $rkey !==
'MFA_E') {
661 $cqid = substr($rkey,4);
662 $mfalist[$cqid] = $posted[$rkey];
667 function Return_AllowedUpdate($CU, $MEMBER, $HB_ENV, $SENDKEY) {
671 $upd_grace = $HB_ENV[
'Ffremain'];
672 $upd_wait = ($upd_grace == 0 ?
"You must update your credentials now." :
673 "You must update your credentials within the next $upd_grace login" . ($upd_grace == 1 ?
'.' :
's.') );
675 $reply_arr = array(
'STATUS' => array(
'CODE' =>3110,
'SEVERITY' =>
'INFO'),
676 'SREQ' => $HB_ENV[
'forceupdate'],
677 'UREQ' => $HB_ENV[
'requpdate'],
678 'DTSERVER' => date(
'YmdHis'),
679 'MEMBER' => $MEMBER );
681 if (is_array($SENDKEY)) {
682 foreach ($SENDKEY as $key => $value) {
683 $reply_arr[$key] = $value;
688 $reply_arr[
'ALLOWUPD'] = array();
690 if ($HB_ENV[
'forceupdate'] != 0) {
691 $reply_arr[
'ALLOWUPD'][
'UPDCANWAIT'] = $upd_grace;
692 $reply_arr[
'ALLOWUPD'][
'UPDWAITPHRASE']=$upd_wait;
694 $reply_arr[
'ALLOWUPD'][
'PASSWORD'] = array(
695 'ALLOW' => (($HB_ENV[
'allowupdate'] & 1) ?
"YES" :
"NO"),
696 'REQ' => (($HB_ENV[
'forceupdate'] & 1) ?
"YES" :
"NO"));
697 $reply_arr[
'ALLOWUPD'][
'EMAIL'] = array(
698 'ALLOW' => (($HB_ENV[
'allowupdate'] & 2) ?
"YES" :
"NO"),
699 'REQ' => (($HB_ENV[
'forceupdate'] & 2) ?
"YES" :
"NO"));
700 $reply_arr[
'ALLOWUPD'][
'CHALLENGE'] = array(
701 'ALLOW' => (($HB_ENV[
'allowupdate'] & 4) ?
"YES" :
"NO"),
702 'REQ' => (($HB_ENV[
'forceupdate'] & 4) ?
"YES" :
"NO"));
703 $reply_arr[
'ALLOWUPD'][
'USERALIAS'] = array(
704 'ALLOW' => (($HB_ENV[
'allowupdate'] & 8) ?
"YES" :
"NO"),
705 'REQ' => (($HB_ENV[
'forceupdate'] & 8) ?
"YES" :
"NO"));
706 $reply_arr[
'ALLOWUPD'][
'PHONE'] = array(
707 'ALLOW' => (($HB_ENV[
'allowupdate'] & 16) ?
"YES" :
"NO"),
708 'REQ' => (($HB_ENV[
'forceupdate'] & 16) ?
"YES" :
"NO"));
713 function Return_ReqUpdate($CU, $MEMBER, $HB_ENV, $SENDKEY) {
714 $dbh = $HB_ENV[
'dbh'];
719 # forceupdate 1 = reset password 720 # forceupdate 4 = reset security w/ challenge questions 721 # forceupdate 16 = reset security w/ access codes 722 # send updRemember if reset pwd or reset security is set 723 $upd_remember = $HB_ENV[
'forceupdate'] & 21;
724 $upd_grace = $HB_ENV[
'Ffremain'];
725 $upd_wait = ($upd_grace == 0 ?
"You must update your credentials now." :
726 "You must update your credentials within the next $upd_grace login" . ($upd_grace == 1 ?
'.' :
's.') );
728 $reply_arr = array(
'STATUS' => array(
'CODE' =>3100,
'SEVERITY' =>
'INFO'),
729 'SREQ' => $HB_ENV[
'forceupdate'],
730 'UREQ' => $HB_ENV[
'requpdate'],
731 'DTSERVER' => date(
'YmdHis'),
732 'MEMBER' => $MEMBER );
734 if (is_array($SENDKEY)) {
735 foreach ($SENDKEY as $key => $value) {
736 $reply_arr[$key] = $value;
740 $reply_arr[
'REQUIREUPD'] = array();
742 if ($HB_ENV[
'forceupdate'] != 0 && $HB_ENV[
'requpdate'] == 0) {
743 $reply_arr[
'REQUIREUPD'][
'UPDCANWAIT'] = $upd_grace;
744 $reply_arr[
'REQUIREUPD'][
'UPDWAITPHRASE']=$upd_wait;
747 $reply_arr[
'REQUIREUPD'][
'UPDREMEMBER']=
'Remember This Device';
751 if ((($HB_ENV[
'forceupdate'] & 4) == 4 && $HB_ENV[
'requpdate'] == 0) || ($HB_ENV[
'requpdate'] & 4) == 4) {
752 # 2-factor and either force reset or not enough questions selected yet 753 # Security Reset: send master list of challenge questions 754 $upd_req = array(
'UPDPHRASEID' =>
'CHALLENGE',
755 'UPDCONFLABEL' =>
'This confidence word is used to identify and prevent phishing attempts when you access home banking through the web. It is not used in this app, but you are asked to set it now in case you later access your account through the web.',
756 'UPDCONFIDENCE' => htmlentities($HB_ENV[
'confidence'], ENT_NOQUOTES | ENT_XML1,
'UTF-8', FALSE),
757 'UPDPHRASECOUNT' => $HB_ENV[
'cu_chgqst_count']);
758 if ($HB_ENV[
'cu_chgqst_count'] > 0) {
759 $upd_req[
'UPDPHRASELABEL'] =
"Please select {$HB_ENV['cu_chgqst_count']} challenge questions";
760 $upd_req[
'UPDCHOICELIST'] = array();
761 $questlist = GetChallengeQuestions(
"DISPLAY", $dbh, $HB_ENV, $MC);
762 foreach ($questlist as $QstValue) {
763 $upd_req[
'UPDCHOICELIST'][][
'CHOICEITEM'] = array(
'CQID' => $QstValue[
'cqid'],
764 'CQTEXT' => htmlentities($QstValue[
'display'], ENT_NOQUOTES | ENT_XML1,
'UTF-8', FALSE));
766 if (($HB_ENV[
'requpdate'] & 4) == 4) {
767 # 'on-demand' update - send current selected questions/responses 768 $upd_req[
'CURRSELECTED'] = array();
769 foreach ($HB_ENV[
'MFA'][
'answers'] as $quest_id => $quest_resp) {
770 $upd_req[
'CURRSELECTED'][][
'SELECTEDITEM'] = array(
'CQID' => $quest_id,
771 'CQRESP' => htmlentities($quest_resp, ENT_NOQUOTES | ENT_XML1,
'UTF-8', FALSE));
775 $reply_arr[
'REQUIREUPD'][][
'REQUPD'] = $upd_req;
778 if ((($HB_ENV[
'forceupdate'] & 1) == 1 && $HB_ENV[
'requpdate'] == 0) || ($HB_ENV[
'requpdate'] & 1) == 1) {
781 $noticesAry = Get_NoticeInfo($dbh, $HB_ENV, $HB_ENV[
'MC'],
"P",
"pwdRules",
false);
784 if ( $noticesAry[
"status"][
"code"] ==
"000" && $noticesAry[
"notice"][0][
"notice_id"] ) {
786 $helpdoc = $noticesAry[
"notice"][0][
"notice_linktarget"];
788 $pwdRequires = Get_PwdRules($dbh, $HB_ENV);
789 $upd_req = array(
'UPDPHRASEID' =>
'PASSWORD',
790 'UPDPHRASELABEL' =>
'Please select a new password.',
791 'PWDRULESLINK' => ($hasRules ? htmlentities($helpdoc, ENT_NOQUOTES | ENT_XML1,
'UTF-8', FALSE) :
''),
792 'PWDRULESLABEL' => ($hasRules ?
'I have read the Recommended Password Guidelines' :
''),
793 'PWDADVLABEL' => ($hasRules ?
'Recommended Guidelines' :
''));
794 foreach ($pwdRequires as $pwdkey => $pwdval) {
795 $pwdkey = strtoupper($pwdkey);
796 $upd_req[
'PWDREQUIRES'][$pwdkey] = $pwdval;
799 $pwdSpecChar = Get_PwdSpecialCharacters();
800 $upd_req[
'PWDREQUIRES'][
'PWDSPECIALCHARS'] = htmlspecialchars($pwdSpecChar, ENT_NOQUOTES | ENT_XML1,
'UTF-8', FALSE);
803 $reply_arr[
'REQUIREUPD'][][
'REQUPD'] = $upd_req;
805 if ((($HB_ENV[
'forceupdate'] & 6) > 0 && $HB_ENV[
'requpdate'] == 0) || ($HB_ENV[
'requpdate'] & 2) == 2) {
806 # verify email is set or email is empty, 807 # or we are sending the CHALLENGE set so include email with it (apps treat email as extra challenge question) 808 $upd_req = array(
'UPDPHRASEID' =>
'EMAIL',
809 'UPDPHRASELABEL' =>
'Please provide your email address.',
810 'CURRENTEMAIL' => htmlentities($HB_ENV[
'Ml'], ENT_NOQUOTES | ENT_XML1,
'UTF-8', FALSE),
811 'CURRENTOPTIN' => $HB_ENV[
'egenl_flag'],
812 'OPTIN_PHRASE' => $MC->msg(
'Yes Email List'));
814 $reply_arr[
'REQUIREUPD'][][
'REQUPD'] = $upd_req;
817 if ((($HB_ENV[
'forceupdate'] & 8) == 8 && $HB_ENV[
'requpdate'] == 0) || ($HB_ENV[
'requpdate'] & 8) == 8) {
819 $maymust = (($HB_ENV[
'Fset2'] & GetFlagsetValue(
'CU2_ALIAS_REQ')) == GetFlagsetValue(
'CU2_ALIAS_REQ') ?
'must' :
'may');
820 $aliaslabel = $MC->combo_msg(
'Username Set', 0,
'#MAYMUST#',
"$maymust");
821 $upd_req = array(
'UPDPHRASEID' =>
'USERALIAS',
822 'UPDPHRASEREQ' => ($HB_ENV[
'alias'] ==
'NONE' ?
'NO' : $HB_ENV[
'alias']),
823 'UPDPHRASELABEL' => htmlentities($aliaslabel, ENT_NOQUOTES | ENT_XML1,
'UTF-8', FALSE));
824 if (($HB_ENV[
'requpdate'] & 8) == 8) {
825 # 'on-demand' update - send current user alias 826 $upd_req[
'CURRENTALIAS'] = htmlentities($HB_ENV[
'useralias'], ENT_NOQUOTES | ENT_XML1,
'UTF-8', FALSE);
828 $reply_arr[
'REQUIREUPD'][][
'REQUPD'] = $upd_req;
830 if ((($HB_ENV[
'forceupdate'] & 16) == 16 && $HB_ENV[
'requpdate'] == 0) || ($HB_ENV[
'requpdate'] & 16) == 16) {
832 $upd_req = array(
'UPDPHRASEID' =>
'PHONES',
833 'UPDCONFLABEL' =>
'This confidence word is used to identify and prevent phishing attempts when you access home banking through the web. It is not used in this app, but you are asked to set it now in case you later access your account through the web.',
834 'UPDCONFIDENCE' => htmlentities($HB_ENV[
'confidence'], ENT_NOQUOTES | ENT_XML1,
'UTF-8', FALSE));
835 # add array entries for phone numbers 836 $upd_req[
'MOBILE'][
'MAXLIMIT'] = MAX_PHONES;
837 $upd_req[
'MOBILE'][
'UPDMBLLABEL'] = $MC->msg(
'TXT Enabled');
838 $phones = GetUserPhones($CU, $UID, $HB_ENV);
839 if (is_array($phones[
'mobile'])) {
840 foreach ($phones[
'mobile'] as $ph => $phnum) {
842 $upd_req[
'MOBILE'][][
'PHONE'] = preg_replace(
'/\D/',
'', $phnum);
845 $reply_arr[
'REQUIREUPD'][][
'REQUPD'] = $upd_req;
851 function Return_ResponseOK($CU, $MEMBER, $SENDKEY, $MESSAGE) {
853 $reply_arr = array(
'STATUS' => array(
'CODE' =>0,
'SEVERITY' =>
'INFO',
'MESSAGE'=> array(
'INFO' => $MESSAGE)),
854 'DTSERVER' => date(
'YmdHis'),
855 'MEMBER' => $MEMBER );
857 if (is_array($SENDKEY)) {
858 foreach ($SENDKEY as $key => $value) {
859 $reply_arr[$key] = $value;
865 function GetPWChange($dbh, $ORG, $MEMBER) {
866 $sqluser =
"SELECT coalesce(pwchange,'2006-01-01 00:00:00.00000-06') as pwchange 868 WHERE user_name = '$MEMBER' ";
870 $mbr_sth = db_query($sqluser, $dbh);
871 if (db_num_rows($mbr_sth) == 1) {
872 $return_ary = db_fetch_assoc($mbr_sth,0);
873 $return_ary[
'pchange'] = strtotime($return_ary[
'pwchange']);
874 $return_ary[
'rowfound'] = 1;
876 $return_ary[
'rowfound'] = 0;
881 function LogFail($dbh, $HB_ENV, $inPost, $failbit) {
882 $updstat = UpdateMemberFailedLogin($dbh, $HB_ENV[
'cu'], $HB_ENV[
'user_name'], $failbit);
883 $p_meta = array(
'UA' => $_SERVER[
'HTTP_USER_AGENT']);
884 $p_hbenv = array(
'Cu' => $inPost[
'ORG'],
'Cn' => $HB_ENV[
'Cn'],
'user_id' => $HB_ENV[
'Uid']);
885 TrackUserLogin($dbh, $p_hbenv, $HB_ENV[
'platform'], $failbit, $_SERVER[
'REMOTE_ADDR'], $p_meta);
888 function LogPass($dbh, &$HB_ENV){
889 # if not online, set the logtrack parameters to NOT decrement the remaining logins 890 $must = ($HB_ENV[
'offline'] !=
'N' || ($HB_ENV[
'forceupdate'] & 29) == 0 ?
'N' :
'Y');
891 $tomorrow = date(
'Y-m-d', mktime(0, 0, 0, date(
"m"), date(
"d") + 1, date(
"Y")));
892 $pchange = ($HB_ENV[
'offline'] !=
'N' ? $tomorrow : $HB_ENV[
'pwchange']);
893 $adjust = ($must ==
'Y' ? 1 : 0);
894 # and fix the corresponding value in HB_ENV 895 $HB_ENV[
'Ffremain']-=$adjust;
898 $HB_ENV[
'MFA'][
'challenge'] = 0;
899 $HB_ENV[
'MFA'][
'authcode']=
'';
900 $HB_ENV[
'MFA'][
'authexpires']=
'';
903 $updstat = UpdateMemberLoginTrack($dbh, $HB_ENV[
'cu'], $HB_ENV[
'user_name'], $must, $pchange, $HB_ENV[
'platform'], $HB_ENV[
'MFA']);
904 $p_meta = array(
'UA' => $_SERVER[
'HTTP_USER_AGENT']);
905 TrackUserLogin($dbh, $HB_ENV, $HB_ENV[
'platform'], 0, $_SERVER[
'REMOTE_ADDR'], $p_meta);
937 function assocArrayToXML($ar, $base=
'APPFEED',$attrs=array()) {
939 $xml =
new SimpleXMLExtended(
"<$base/>");
940 if ( isset($attrs) && is_array($attrs)) {
941 foreach ($attrs as $key => $value) {
942 if(preg_match(
"/^[a-z_]+[a-z0-9\:\-\.\_]*[^:]*$/i", $key, $matches) && $matches[0] == $key) {
943 $xml->addAttribute($key, $value);
947 $f = create_function(
'$f,$c,$a',
' 948 foreach($a as $k=>$v) { 950 if (is_numeric($k)) { 953 $ch=$c->addChild($k); 954 if(isset($v["@attributes"]) && is_array($v["@attributes"])) { 955 foreach($v["@attributes"] as $key => $value) { 956 if(preg_match("/^[a-z_]+[a-z0-9\:\-\.\_]*[^:]*$/i", $key, $matches) && $matches[0] == $key) { 957 // only add the attribute if the name is valid 958 $value = $value === true ? "true" : $value; 959 $value = $value === false ? "false" : $value; 960 $ch->addAttribute($key, $value); 963 unset($v["@attributes"]); //remove the key from the array once done. 965 // check if it has a value directly stored as string 966 if(isset($v["@cdata"])) { 967 $value = $v["@cdata"]; 968 $value = $value === true ? "true" : $value; 969 $value = $value === false ? "false" : $value; 970 $ch->addCData($value); 971 unset($v["@cdata"]); //remove the key from the array once done. 980 if (is_array($ar) ) {
983 $return = $xml->asXML();
985 $return = str_replace(
'<?xml version="1.0"?>',
'',$return);
991 class SimpleXMLExtended
extends SimpleXMLElement {
992 public function addCData($cdata_text) {
993 $node = dom_import_simplexml($this);
994 $no = $node->ownerDocument;
995 $node->appendChild($no->createCDATASection($cdata_text));
1006 function MFQ_send_chall($dbh, $HB_ENV, $MC) {
1008 # sending all questions regardless of '1 random' setting for cu 1009 # updated 9/12 to recognize '1 random' setting 1014 $HB_ENV[
'cu'] = $HB_ENV[
'Cu'];
1015 $HB_ENV[
'HCUPOST'][
'username'] = $HB_ENV[
'Cn'];
1016 $HB_ENV[
'username'] = $HB_ENV[
'Cn']; # yes, the
function really uses both
1017 $HB_ENV[
'HCUPOST'][
'Flang'] =
'en_US';
1018 $HB_ENV[
'flagset2'] = $HB_ENV[
'Fset2'];
1020 $MemberChallengeQuestions_ary=GetChallengeQuestions(
"CHALLENGE", $dbh, $HB_ENV );
1022 $reply_arr = array(
'STATUS' => array(
'CODE' =>3000,
'SEVERITY' =>
'ERROR'),
1023 'DTSERVER' => date(
'YmdHis') );
1026 $reply_arr[
'MFA'] = array();
1027 $reply_arr[
'MFA'][
'AUTHREQ'] =
'MFQ';
1028 $reply_arr[
'MFA'][
'MFABUNDLE'] = $HB_ENV[
'mfaBundle'];
1037 # and now add mfa questions, if any were found 1038 if (count($MemberChallengeQuestions_ary)) {
1039 foreach ((array) $MemberChallengeQuestions_ary as $chakey => $mfaitem) {
1040 $itm_arr = array(
'MFACHALLENGE' => array(
1041 'MFAPHRASEID' =>
"MFA_{$mfaitem['cqid']}",
1042 'MFAPHRASELABEL' =>
"{$mfaitem['display']}"));
1044 $reply_arr[
'MFA'][] = $itm_arr;