⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 securityhandler.cc

📁 这是一个做pdf阅读器的源代码文件,是大家学习阅读器资料的很好参考
💻 CC
字号:
//========================================================================//// SecurityHandler.cc//// Copyright 2004 Glyph & Cog, LLC////========================================================================#include <aconf.h>#ifdef USE_GCC_PRAGMAS#pragma implementation#endif#include "GString.h"#include "PDFDoc.h"#include "Decrypt.h"#include "Error.h"#include "GlobalParams.h"#if HAVE_XPDFCORE#  include "XPDFCore.h"#elif HAVE_WINPDFCORE#  include "WinPDFCore.h"#endif#ifdef ENABLE_PLUGINS#  include "XpdfPluginAPI.h"#endif#include "SecurityHandler.h"//------------------------------------------------------------------------// SecurityHandler//------------------------------------------------------------------------SecurityHandler *SecurityHandler::make(PDFDoc *docA, Object *encryptDictA) {  Object filterObj;  SecurityHandler *secHdlr;#ifdef ENABLE_PLUGINS  XpdfSecurityHandler *xsh;#endif  encryptDictA->dictLookup("Filter", &filterObj);  if (filterObj.isName("Standard")) {    secHdlr = new StandardSecurityHandler(docA, encryptDictA);  } else if (filterObj.isName()) {#ifdef ENABLE_PLUGINS    if ((xsh = globalParams->getSecurityHandler(filterObj.getName()))) {      secHdlr = new ExternalSecurityHandler(docA, encryptDictA, xsh);    } else {#endif      error(-1, "Couldn't find the '%s' security handler",	    filterObj.getName());      secHdlr = NULL;#ifdef ENABLE_PLUGINS    }#endif  } else {    error(-1, "Missing or invalid 'Filter' entry in encryption dictionary");    secHdlr = NULL;  }  filterObj.free();  return secHdlr;}SecurityHandler::SecurityHandler(PDFDoc *docA) {  doc = docA;}SecurityHandler::~SecurityHandler() {}GBool SecurityHandler::checkEncryption(GString *ownerPassword,				       GString *userPassword) {  void *authData;  GBool ok;  int i;  if (ownerPassword || userPassword) {    authData = makeAuthData(ownerPassword, userPassword);  } else {    authData = NULL;  }  ok = authorize(authData);  if (authData) {    freeAuthData(authData);  }  for (i = 0; !ok && i < 3; ++i) {    if (!(authData = getAuthData())) {      break;    }    ok = authorize(authData);    if (authData) {      freeAuthData(authData);    }  }  if (!ok) {    error(-1, "Incorrect password");  }  return ok;}//------------------------------------------------------------------------// StandardSecurityHandler//------------------------------------------------------------------------class StandardAuthData {public:  StandardAuthData(GString *ownerPasswordA, GString *userPasswordA) {    ownerPassword = ownerPasswordA;    userPassword = userPasswordA;  }  ~StandardAuthData() {    if (ownerPassword) {      delete ownerPassword;    }    if (userPassword) {      delete userPassword;    }  }  GString *ownerPassword;  GString *userPassword;};StandardSecurityHandler::StandardSecurityHandler(PDFDoc *docA,						 Object *encryptDictA):  SecurityHandler(docA){  Object versionObj, revisionObj, lengthObj;  Object ownerKeyObj, userKeyObj, permObj, fileIDObj;  Object fileIDObj1;  Object cryptFiltersObj, streamFilterObj, stringFilterObj;  Object cryptFilterObj, cfmObj, cfLengthObj;  Object encryptMetadataObj;  ok = gFalse;  fileID = NULL;  ownerKey = NULL;  userKey = NULL;  encryptDictA->dictLookup("V", &versionObj);  encryptDictA->dictLookup("R", &revisionObj);  encryptDictA->dictLookup("Length", &lengthObj);  encryptDictA->dictLookup("O", &ownerKeyObj);  encryptDictA->dictLookup("U", &userKeyObj);  encryptDictA->dictLookup("P", &permObj);  doc->getXRef()->getTrailerDict()->dictLookup("ID", &fileIDObj);  if (versionObj.isInt() &&      revisionObj.isInt() &&      ownerKeyObj.isString() && ownerKeyObj.getString()->getLength() == 32 &&      userKeyObj.isString() && userKeyObj.getString()->getLength() == 32 &&      permObj.isInt()) {    encVersion = versionObj.getInt();    encRevision = revisionObj.getInt();    encAlgorithm = cryptRC4;    // revision 2 forces a 40-bit key - some buggy PDF generators    // set the Length value incorrectly    if (encRevision == 2 || !lengthObj.isInt()) {      fileKeyLength = 5;    } else {      fileKeyLength = lengthObj.getInt() / 8;    }    encryptMetadata = gTrue;    //~ this currently only handles a subset of crypt filter functionality    if (encVersion == 4 && encRevision == 4) {      encryptDictA->dictLookup("CF", &cryptFiltersObj);      encryptDictA->dictLookup("StmF", &streamFilterObj);      encryptDictA->dictLookup("StrF", &stringFilterObj);      if (cryptFiltersObj.isDict() &&	  streamFilterObj.isName() &&	  stringFilterObj.isName() &&	  !strcmp(streamFilterObj.getName(), stringFilterObj.getName())) {	if (cryptFiltersObj.dictLookup(streamFilterObj.getName(),				       &cryptFilterObj)->isDict()) {	  cryptFilterObj.dictLookup("CFM", &cfmObj);	  if (cfmObj.isName("V2")) {	    encVersion = 2;	    encRevision = 3;	    if (cryptFilterObj.dictLookup("Length", &cfLengthObj)->isInt()) {	      //~ according to the spec, this should be cfLengthObj / 8	      fileKeyLength = cfLengthObj.getInt();	    }	    cfLengthObj.free();	  } else if (cfmObj.isName("AESV2")) {	    encVersion = 2;	    encRevision = 3;	    encAlgorithm = cryptAES;	    if (cryptFilterObj.dictLookup("Length", &cfLengthObj)->isInt()) {	      //~ according to the spec, this should be cfLengthObj / 8	      fileKeyLength = cfLengthObj.getInt();	    }	    cfLengthObj.free();	  }	  cfmObj.free();	}	cryptFilterObj.free();      }      stringFilterObj.free();      streamFilterObj.free();      cryptFiltersObj.free();      if (encryptDictA->dictLookup("EncryptMetadata",				   &encryptMetadataObj)->isBool()) {	encryptMetadata = encryptMetadataObj.getBool();      }      encryptMetadataObj.free();    }    permFlags = permObj.getInt();    ownerKey = ownerKeyObj.getString()->copy();    userKey = userKeyObj.getString()->copy();    if (encVersion >= 1 && encVersion <= 2 &&	encRevision >= 2 && encRevision <= 3) {      if (fileIDObj.isArray()) {	if (fileIDObj.arrayGet(0, &fileIDObj1)->isString()) {	  fileID = fileIDObj1.getString()->copy();	} else {	  fileID = new GString();	}	fileIDObj1.free();      } else {	fileID = new GString();      }      ok = gTrue;    } else {      error(-1, "Unsupported version/revision (%d/%d) of Standard security handler",	    encVersion, encRevision);    }  } else {    error(-1, "Weird encryption info");  }  if (fileKeyLength > 16) {    fileKeyLength = 16;  }  fileIDObj.free();  permObj.free();  userKeyObj.free();  ownerKeyObj.free();  lengthObj.free();  revisionObj.free();  versionObj.free();}StandardSecurityHandler::~StandardSecurityHandler() {  if (fileID) {    delete fileID;  }  if (ownerKey) {    delete ownerKey;  }  if (userKey) {    delete userKey;  }}void *StandardSecurityHandler::makeAuthData(GString *ownerPassword,					    GString *userPassword) {  return new StandardAuthData(ownerPassword ? ownerPassword->copy()			                    : (GString *)NULL,			      userPassword ? userPassword->copy()			                   : (GString *)NULL);}void *StandardSecurityHandler::getAuthData() {#if HAVE_XPDFCORE  XPDFCore *core;  GString *password;  if (!(core = (XPDFCore *)doc->getGUIData()) ||      !(password = core->getPassword())) {    return NULL;  }  return new StandardAuthData(password, password->copy());#elif HAVE_WINPDFCORE  WinPDFCore *core;  GString *password;  if (!(core = (WinPDFCore *)doc->getGUIData()) ||      !(password = core->getPassword())) {    return NULL;  }  return new StandardAuthData(password, password->copy());#else  return NULL;#endif}void StandardSecurityHandler::freeAuthData(void *authData) {  delete (StandardAuthData *)authData;}GBool StandardSecurityHandler::authorize(void *authData) {  GString *ownerPassword, *userPassword;  if (!ok) {    return gFalse;  }  if (authData) {    ownerPassword = ((StandardAuthData *)authData)->ownerPassword;    userPassword = ((StandardAuthData *)authData)->userPassword;  } else {    ownerPassword = NULL;    userPassword = NULL;  }  if (!Decrypt::makeFileKey(encVersion, encRevision, fileKeyLength,			    ownerKey, userKey, permFlags, fileID,			    ownerPassword, userPassword, fileKey,			    encryptMetadata, &ownerPasswordOk)) {    return gFalse;  }  return gTrue;}#ifdef ENABLE_PLUGINS//------------------------------------------------------------------------// ExternalSecurityHandler//------------------------------------------------------------------------ExternalSecurityHandler::ExternalSecurityHandler(PDFDoc *docA,						 Object *encryptDictA,						 XpdfSecurityHandler *xshA):  SecurityHandler(docA){  encryptDictA->copy(&encryptDict);  xsh = xshA;  encAlgorithm = cryptRC4; //~ this should be obtained via getKey  ok = gFalse;  if (!(*xsh->newDoc)(xsh->handlerData, (XpdfDoc)docA,		      (XpdfObject)encryptDictA, &docData)) {    return;  }  ok = gTrue;}ExternalSecurityHandler::~ExternalSecurityHandler() {  (*xsh->freeDoc)(xsh->handlerData, docData);  encryptDict.free();}void *ExternalSecurityHandler::makeAuthData(GString *ownerPassword,					    GString *userPassword) {  char *opw, *upw;  void *authData;  opw = ownerPassword ? ownerPassword->getCString() : (char *)NULL;  upw = userPassword ? userPassword->getCString() : (char *)NULL;  if (!(*xsh->makeAuthData)(xsh->handlerData, docData, opw, upw, &authData)) {    return NULL;  }  return authData;}void *ExternalSecurityHandler::getAuthData() {  void *authData;  if (!(*xsh->getAuthData)(xsh->handlerData, docData, &authData)) {    return NULL;  }  return authData;}void ExternalSecurityHandler::freeAuthData(void *authData) {  (*xsh->freeAuthData)(xsh->handlerData, docData, authData);}GBool ExternalSecurityHandler::authorize(void *authData) {  char *key;  int length;  if (!ok) {    return gFalse;  }  permFlags = (*xsh->authorize)(xsh->handlerData, docData, authData);  if (!(permFlags & xpdfPermissionOpen)) {    return gFalse;  }  if (!(*xsh->getKey)(xsh->handlerData, docData, &key, &length, &encVersion)) {    return gFalse;  }  if ((fileKeyLength = length) > 16) {    fileKeyLength = 16;  }  memcpy(fileKey, key, fileKeyLength);  (*xsh->freeKey)(xsh->handlerData, docData, key, length);  return gTrue;}#endif // ENABLE_PLUGINS

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -