Windows凭据管理
		
		
				
				
				原文:http://www.cppblog.com/Squirrel/archive/2006/05/20/7445.html
		
		
				       题目中的Windows凭据(Credential)其实就是指用户帐户和口令。最近项目中存在一台Windows(PC)机去管理服务器(Server),这之中就设计到服务器管理员权限的问题。需要用户对Windows上存储的用户名和密码进行管理。
       在Windows XP和Server 2003 中都已存在了“存储的用户名和密码”。在XP中,通过控制面板中的用户帐户-〉选择用户-〉管理我的网络密码。而在Server 2003中,则在控制面板下直接有“存储的用户名和密码”项。
       我们调用一些API,如WTSOpenServer,QueryServiceStatus,NetUserEnum等等涉及到RPC的,只要当前用户存储有目标远程机的权限合适的凭据,则这些API就不会因产生ERROR_ACCESS_DENIED而执行失败。因为我还不Windows的底层是如何进行控制的,比如,是否调用了SSPI,所以,执行这些API时,我只能向用户要管理员口令。但又不可能每次都让用户去输入一遍用户名和密码,那么,也就需要保存密码。
       既然保存了密码,就必须考虑删除密码,那么密码管理的问题也就来了。说到密码管理,我在前些年看电视的时候,看到介绍一个叫什么“网络螃蟹”的网站,他就是专门提供个人密码管理的,当时我就想,有人会去把自己的密码交给别人打理吗?这好像不大可能。后来也就没听到什么网络螃蟹横行的消息。
       现在我的项目中,如果用户有了一台机器(PC)的密码,那么,他就有了N台服务器的管理员权限。这当然是不被允许的了。怎么办?
       找了一些API,是Authentication Functions系列的。于是,下面一个小实验代码就是想来枚举用户凭据的。 #include <windows.h>
#include <windows.h>
 #include <WinCred.h>
#include <WinCred.h>

 int main()
int main() {
{

 DWORD dwCount = 0;
  DWORD dwCount = 0;
 PCREDENTIAL * pCredArray = NULL ;
  PCREDENTIAL * pCredArray = NULL ;


 if( CredEnumerate( NULL, 0, &dwCount, &pCredArray ) )
  if( CredEnumerate( NULL, 0, &dwCount, &pCredArray ) ) {
{


 for( DWORD dwIndex = 0; dwIndex < dwCount; dwIndex++)
    for( DWORD dwIndex = 0; dwIndex < dwCount; dwIndex++) {
{
 PCREDENTIAL pCredential = pCredArray[dwIndex];
      PCREDENTIAL pCredential = pCredArray[dwIndex];

 cout << "*********************************\r\n";
      cout << "*********************************\r\n";

 cout<<  "Flags: " << pCredential->Flags << "\n"
      cout<<  "Flags: " << pCredential->Flags << "\n"
 <<  "Type:  " <<  pCredential->Type << "\n"
          <<  "Type:  " <<  pCredential->Type << "\n"
 <<  "Name:  " << pCredential->TargetName << "\n"
          <<  "Name:  " << pCredential->TargetName << "\n"
 <<  "Persist: "<< pCredential->Persist  <<  "\n"
          <<  "Persist: "<< pCredential->Persist  <<  "\n"
 <<  "User:  " <<  pCredential->UserName <<  "\n";
          <<  "User:  " <<  pCredential->UserName <<  "\n";

 cout << "Data:  \r\n";
      cout << "Data:  \r\n";

 char szHexBuffer[256] = "";
      char szHexBuffer[256] = "";
 char szAsciiBuffer[256] = "";
      char szAsciiBuffer[256] = "";
 char szHex[16];
      char szHex[16];
 char szAscii[2];
      char szAscii[2];
 DWORD dwByte;
      DWORD dwByte;

 for (dwByte = 0; dwByte < pCredential->CredentialBlobSize; dwByte++)
      for (dwByte = 0; dwByte < pCredential->CredentialBlobSize; dwByte++)

 
       {
{
 BYTE byte1 = pCredential->CredentialBlob[dwByte];
        BYTE byte1 = pCredential->CredentialBlob[dwByte];
 sprintf(szHex, "%2.2X ", byte1);
        sprintf(szHex, "%2.2X ", byte1);
 szAscii[1] = '\0';
        szAscii[1] = '\0';

 if (byte1 >= 32 && byte1 < 128)
        if (byte1 >= 32 && byte1 < 128)
 szAscii[0] = (UCHAR)byte1;
          szAscii[0] = (UCHAR)byte1;
 else
        else
 szAscii[0] = ' ';
          szAscii[0] = ' ';

 strcat(szHexBuffer, szHex);
        strcat(szHexBuffer, szHex);
 strcat(szAsciiBuffer, szAscii);
        strcat(szAsciiBuffer, szAscii);

 if (dwByte == pCredential->CredentialBlobSize - 1
        if (dwByte == pCredential->CredentialBlobSize - 1 
 || dwByte % 16 == 15)
          || dwByte % 16 == 15)

 
         {
{
 printf("%-50s %s\r\n", szHexBuffer, szAsciiBuffer);
          printf("%-50s %s\r\n", szHexBuffer, szAsciiBuffer);
 szHexBuffer[0] = '\0';
          szHexBuffer[0] = '\0';
 szAsciiBuffer[0] = '\0';
          szAsciiBuffer[0] = '\0';
 }
        }

 }
      }

 cout << "*********************************\r\n";
      cout << "*********************************\r\n";

 }
    }

 CredFree( pCredArray );
    CredFree( pCredArray );
 }
  }
 //system( "rundll32 keymgr.dll,KRShowKeyMgr");
  //system( "rundll32 keymgr.dll,KRShowKeyMgr");
 return 0;
  return 0;
 }
}
       后来,本着“编程的最高境界就是不编程”的精神,我想,如果直接把Windows的那个“存储的用户名和密码”对话框调出来用用不也可以吗。用ProcessExplorer,找到一个叫keymgr.dll的东西,嗯,估计对话框就在里面。
       在“运行”中输入“control keymgr.dll”或“rundll32 keymgr.dll,KRShowKeyMgr”,对话框就出来了。
       又省事了! 
		 
	posted on 2006-05-21 02:43 
Jerry Cat 阅读(766) 
评论(0)  编辑 收藏 引用