Aug 17

分析pw的通行证原理 不指定

bkkkd , 00:04 , 开发应用 , 评论(4) , 引用(0) , 阅读(6000) , Via 本站原创 | |
其实这个很早以前也研究过
但是由于没有记录下
时间一长了就忘记了

实现程序主要有:require/passport_server.php,passport_client.php

每次登录或注册时,服务端都会包含require/passport_server.php

来看看passport_server.php里面有什么东西

<?php
!function_exists('readover') && exit('Forbidden');

if(!$passport_ifopen || $passport_type != 'server'){
  Showmsg('passport_close');
}

!$forward && $forward = $db_cmsurl;
$clienturl=explode("\n",str_replace("\r","",$passport_urls));

//题外话,这段代码我看不出有什么特别,只觉得好像一无用处
//因为passort_urls就是在设置服务器端的<通行证客户端地址>如果我有好几个,
//他也只是取第一个不是空的就可以了。这样的话,完全是没有作用,
//还不如直接定义一个客户端地址
$jumpurl='';
while(!$jumpurl){
  $jumpurl=array_shift($clienturl);
}
if(!$jumpurl){
  Showmsg('undefined_action');
}

$userdb = array();
foreach($clienturl as $key=>$val){
  if($val && $val != $jumpurl){
    $userdb['url'] .= $userdb['url'] ? ",$val" : $val;
  }
}

$rt=$db->get_one("SELECT uid,username,password,email,rvrc,money,credit FROM pw_user WHERE uid='$winduid'");

//这里就是接口所用到的其中一个重要数据
//有占类似支付宝的接口
//但显然是后其更改进的
//看下面的注释
$userdb['uid']    = $rt['uid'];
$userdb['username']  = $rt['username'];
$userdb['password']  = $rt['password'];
$userdb['email']  = $rt['email'];
$userdb['rvrc']    = $rt['rvrc'];
$userdb['money']  = $rt['money'];
$userdb['credit']  = $rt['credit'];
$userdb['time']    = $timestamp;
$userdb['cktime']  = $cktime;

//看这里是将数据转成字符串
$userdb_encode='';
foreach($userdb as $key=>$val){
  $userdb_encode .= $userdb_encode ? "&$key=$val" : "$key=$val";
}
//这里就是跟支付宝不同的地方,支付宝在这里是公开的。而这里使用了StrCode加密。
//相对来说是比支付宝要安全很多。但也可能出现错误,因为strcode可能会出显“=”号
//现在直接用str_replace换掉“=”号,这种做法不可取。因为这样做为程序造成一个不稳定因素
//这应该是lyn经常会说pw灵义事件之一了
//其实这个str_replace 是完全没有必要的。因为下面使用了rawurlencode

$db_hash=$passport_key;
$userdb_encode=str_replace('=','',StrCode($userdb_encode));

if($action=='login'){

  //verify,就是跟支付宝差不多的东西。确保数据没有变更改过。
  $verify = md5("login$userdb_encode$forward$passport_key");

  //主要提供三个变量到客户端去就可以完成服务端的工作了。
  ObHeader("$jumpurl/passport_client.php?action=login&userdb=".rawurlencode($userdb_encode)."&forward=".rawurlencode($forward)."&verify=".rawurlencode($verify));
}elseif($action=='quit'){
  $verify = md5("quit$userdb_encode$forward$passport_key");
  ObHeader("$jumpurl/passport_client.php?action=quit&userdb=".rawurlencode($userdb_encode)."&forward=".rawurlencode($forward)."&verify=".rawurlencode($verify));
}
?>


当客户端接收到服务器提交的三个变量后

<?php
require_once('global.php');
require_once(R_P.'mod/checkpass_mod.php');

if(!$passport_ifopen || $passport_type != 'client'){
  exit("Passport closed(VeryCMS)");
}

if(md5($action.$userdb.$forward.$passport_key) != $verify){
  exit('Illegal request(VeryCMS)');
}
$_db_hash=$db_hash;

//还原用户数据
$db_hash=$passport_key;
parse_str(StrCode($userdb,'DECODE'),$userdb);

if($action=='login'){
  foreach($userdb as $key=>$val){
    $userdb[$key] = addslashes($val);
  }
  if(!$userdb['time'] || !$userdb['username'] || !$userdb['password'] || !$userdb['email']){
    exit("Lack of parameters(VeryCMS)");
  }
  if($timestamp-$userdb['time']>3600){
    exit('Passport request expired(VeryCMS)');
  }
  
  //题外话:这里里verycms的一段特殊接口,不知道为什么会另外写一般关于verycms的接口,而不是使用一个统一的接口,
  //如果以后还其它的程序是不是还要另外加一段程序?
  //verycms passport group right
  $groupright=1;
  include_once(D_P.'data/cache/passport.php');
  if($ps_combine){
    $db->select_db($ps_bbsdbname);
    $PW = $ps_bbspre;

    $gp = $db->get_one("SELECT hk_value FROM pw_hack WHERE hk_name='bg_groups'");
    $rt = $db->get_one("SELECT groupid,memberid FROM pw_members WHERE uid='$userdb[uid]'");
    Add_S($rt);
    Add_S($gp);

    $groupid = $rt['groupid'] == '-1' ? $rt['memberid'] : $rt['groupid'];
    if($gp['hk_value'] && strpos($gp['hk_value'],",$groupid,")===false){
      $groupright=0;
      $forward .= "/?nogroupright";
    }
    include (D_P.'data/sql_config.php');
    $db->select_db($dbname);
  }
  //verycms passport group right

  if($groupright){
    $user_field = array('username','password','email');
    $credit_field = array('rvrc','money','credit');

    $sql='';
    foreach($user_field as $key=>$val){
      $sql .= ','.$val;
    }
    foreach($credit_field as $key=>$val){
      $sql .= ','.$val;
    }
    //先看查是否有这个用户,使用的是用户名作关联,这个方案是不错,毕竟不是所有论坛程序都会有uid,
    //pw的另一套程序ofstar
    $rt=$db->get_one("SELECT uid $sql FROM pw_user WHERE username='$userdb[username]'");
    if($rt){
      $sql='';
      foreach($userdb as $key=>$val){
        if($rt[$key] != $val){
          if(in_array($key,$user_field)){
            $sql  .= $sql ? ",$key='$val'" : "$key='$val'";
          }elseif(in_array($key,$credit_field) && strpos(",$passport_credit,",",$key,")!==false){
            $sql .= $sql ? ",$key='$val'" : "$key='$val'";
          }
        }
      }
      if($sql){
        $db->update("UPDATE pw_user SET $sql WHERE uid='$rt[uid]'");
        $db->update("UPDATE pw_domain SET bbsuid='$userdb[uid]',username='$userdb[username]' WHERE uid='$rt[uid]'");
      }
      $winduid = $rt['uid'];
    }else{
      $sql1=$sql2='';
      foreach($userdb as $key=>$val){
        if(in_array($key,$user_field)){
          $sql1 .= $sql1 ? ','.$key  : $key;
          $sql2 .= $sql2 ? ",'$val'" : "'$val'";
        }elseif(in_array($key,$credit_field) && strpos(",$passport_credit,",",$key,")!==false){
          $sql1 .= $sql1 ? ','.$key  : $key;
          $sql2 .= $sql2 ? ",'$val'" : "'$val'";
        }
      }
      //刚开始我在想,论坛的用户是怎么在blog里直接建一个帐呢?原来就是用Replace关键字来建的。
      //下面三个$db->update都是会对数据作出更改或添加。可是我很奇怪。
      //为什么在register.php文件里会对以下的数据进行过滤,而在这里却一点都不过滤就直接使用呢?
      //是不是很相信,使用pwblog程序的人只会使用pwfourm呢?
      //但就算都是用pwfourm,那用户使用中文呢?
      //有点不负责任的感觉。
      $db->update("REPLACE INTO pw_user($sql1,groupid,memberid,gender,regdate,signchange) VALUES($sql2,'-1','8','0','$timestamp','1')");
      $winduid = $db->insert_id();
      //
      $db->update("REPLACE INTO pw_domain(uid,bbsuid,username,blogname) VALUES ('$winduid','$userdb[uid]','$userdb[username]','$userdb[username]')");

      $db->update("UPDATE pw_bloginfo SET newmember='$userdb[username]',totalmember=totalmember+1 WHERE id='1'");
    }

    $db_hash=$_db_hash;
    $windpwd = confuse($userdb['password']);

    Cookie("bloguser",StrCode($winduid."\t".$windpwd),$userdb['cktime']);
    Cookie('lastvisit','',0);
    Loginipwrite();
    if($userdb['url']){
      $clienturl = explode(',',$userdb['url']);
      $jumpurl='';
      while(!$jumpurl){
        $jumpurl=array_shift($clienturl);
      }
      $userdb['url'] = implode(',',$clienturl);
    }
  }

  if($jumpurl){
    $userdb_encode='';
    foreach($userdb as $key=>$val){
      $userdb_encode .= $userdb_encode ? "&$key=$val" : "$key=$val";
    }
    $db_hash=$passport_key;
    $userdb_encode=str_replace('=','',StrCode($userdb_encode));

    $verify = md5("login$userdb_encode$forward$passport_key");
    ObHeader("$jumpurl/passport_client.php?action=login&userdb=".rawurlencode($userdb_encode)."&forward=".rawurlencode($forward)."&verify=".rawurlencode($verify));
  }else{
    ObHeader($forward ? $forward : $passport_serverurl);
  }
}elseif($action=='quit'){
  $db_hash=$_db_hash;
  Loginout();

  if($userdb['url']){
    $clienturl = explode(',',$userdb['url']);
    $jumpurl='';
    while(!$jumpurl){
      $jumpurl=array_shift($clienturl);
    }
    $userdb['url'] = implode(',',$clienturl);
  }

  if($jumpurl){
    $userdb_encode='';
    foreach($userdb as $key=>$val){
      $userdb_encode .= $userdb_encode ? "&$key=$val" : "$key=$val";
    }
    $db_hash=$passport_key;
    $userdb_encode=str_replace('=','',StrCode($userdb_encode));

    $verify = md5("quit$userdb_encode$forward$passport_key");
    ObHeader("$jumpurl/passport_client.php?action=quit&userdb=".rawurlencode($userdb_encode)."&forward=".rawurlencode($forward)."&verify=".rawurlencode($verify));
  }else{
    ObHeader($forward ? $forward : $passport_serverurl);
  }
}

function Loginipwrite($winduid){
  global $db,$timestamp,$onlineip;

  $logininfo="$onlineip|$timestamp|6";
  $db->update("UPDATE pw_user SET lastvisit=thisvisit,thisvisit='$timestamp',onlineip='$logininfo' WHERE uid='$winduid'");
}
?>

hargreaves Homepage
August 19, 2007 02:50
这是一条隐藏评论或留言。您需要以合适的身份登入后才能看到。
bkkkd 回复于 August 19, 2007 09:55
那只能算微软的一部分
不过.net确实很强大
强大=耗资源
Ella
August 19, 2007 02:31
这是一条隐藏评论或留言。您需要以合适的身份登入后才能看到。
bkkkd 回复于 August 19, 2007 09:55
fear
lee Homepage
August 18, 2007 14:57
这是一条隐藏评论或留言。您需要以合适的身份登入后才能看到。
bkkkd 回复于 August 18, 2007 16:55
开源不等于免费
只是某些素质低的人把开源当免费
hargreaves Homepage
August 17, 2007 12:34
这是一条隐藏评论或留言。您需要以合适的身份登入后才能看到。
bkkkd 回复于 August 17, 2007 13:43
php的主要应用方面是在于web
跟微软的好像没有多少可比之处
分页: 1/1 第一页 1 最后页
发表评论
表情
emotemotemotemotemot
emotemotemotemotemot
emotemotemotemotemot
emotemotemotemotemot
emotemotemotemotemot
打开HTML
打开UBB
打开表情
隐藏
记住我
昵称   密码   游客无需密码
网址   电邮   [注册]