corrected a few bugs in the cert cleaning method. Added feedback to the GUI and error codes for the cert cleaning function of rspeers

git-svn-id: http://svn.code.sf.net/p/retroshare/code/trunk@4580 b45a01b8-16f6-495d-af2f-9b41ad6348cc
This commit is contained in:
csoler 2011-08-30 21:49:49 +00:00
parent 3ff69a1be5
commit 8941aa5991
6 changed files with 81 additions and 32 deletions

View File

@ -27,7 +27,7 @@
#include <iostream> #include <iostream>
#include <string.h> //strlen #include <string.h> //strlen
#include <list> #include <list>
#include <retroshare/rspeers.h>
/* /*
Method for cleaning up the certificate. This method removes any unnecessay white spaces and unnecessary Method for cleaning up the certificate. This method removes any unnecessay white spaces and unnecessary
new line characters in the certificate. Also it makes sure that there are 64 characters per line in new line characters in the certificate. Also it makes sure that there are 64 characters per line in
@ -41,8 +41,10 @@ end tag we take care of cases like ----- END XPGP . Here extra empty spaces h
introduced and the actual tag should have been -----END XPGP introduced and the actual tag should have been -----END XPGP
*/ */
std::string cleanUpCertificate(const std::string& badCertificate)
std::string cleanUpCertificate(const std::string& badCertificate,int& error_code)
{ {
error_code = RS_PEER_CERT_CLEANING_CODE_UNKOWN_ERROR ; // default
/* /*
Buffer for storing the cleaned certificate. In certain cases the Buffer for storing the cleaned certificate. In certain cases the
cleanCertificate can be larger than the badCertificate cleanCertificate can be larger than the badCertificate
@ -79,11 +81,14 @@ std::string cleanUpCertificate(const std::string& badCertificate)
//Boolean flag showing if the begin tag or the end tag has been found //Boolean flag showing if the begin tag or the end tag has been found
bool found=false; bool found=false;
/* /*
Calculating the value of the beginCertStartIdx1 and beginCertStartIdx2. Here we first locate the occurance of ----- and then Calculating the value of the beginCertStartIdx1 and beginCertStartIdx2. Here
the location of BEGIN. Next we check if there are any non space or non new-line characters between their occureance. If there are any other we first locate the occurance of ----- and then the location of BEGIN. Next
characters between the two(----- and BEGIN), other than space and new line then it means that it is the certificate begin tag. we check if there are any non space or non new-line characters between their
Here we take care of the fact that we may have introduced some spaces and newlines in the begin tag by mistake. This occureance. If there are any other characters between the two(----- and
takes care of the spaces and newlines between ----- and BEGIN. BEGIN), other than space and new line then it means that it is the
certificate begin tag. Here we take care of the fact that we may have
introduced some spaces and newlines in the begin tag by mistake. This takes
care of the spaces and newlines between ----- and BEGIN.
*/ */
while(found==false && (beginCertStartIdx1=badCertificate.find(commonTag,tmpIdx))!=std::string::npos) while(found==false && (beginCertStartIdx1=badCertificate.find(commonTag,tmpIdx))!=std::string::npos)
@ -114,12 +119,14 @@ std::string cleanUpCertificate(const std::string& badCertificate)
if(!found) if(!found)
{ {
std::cerr<<"Certificate corrupted beyond repair: No <------BEGIN > tag"<<std::endl; std::cerr<<"Certificate corrupted beyond repair: No <------BEGIN > tag"<<std::endl;
error_code = RS_PEER_CERT_CLEANING_CODE_NO_BEGIN_TAG ;
return badCertificate; return badCertificate;
} }
beginCertEndIdx=badCertificate.find(commonTag,beginCertStartIdx2); beginCertEndIdx=badCertificate.find(commonTag,beginCertStartIdx2);
if(beginCertEndIdx==std::string::npos) if(beginCertEndIdx==std::string::npos)
{ {
std::cerr<<"Certificate corrupted beyond repair: No <------BEGIN > tag"<<std::endl; std::cerr<<"Certificate corrupted beyond repair: No <------BEGIN > tag"<<std::endl;
error_code = RS_PEER_CERT_CLEANING_CODE_NO_BEGIN_TAG ;
return badCertificate; return badCertificate;
} }
tmpIdx=beginCertEndIdx+strlen(commonTag); tmpIdx=beginCertEndIdx+strlen(commonTag);
@ -159,12 +166,14 @@ std::string cleanUpCertificate(const std::string& badCertificate)
if(!found) if(!found)
{ {
std::cerr<<"Certificate corrupted beyond repair: No <------END > tag"<<std::endl; std::cerr<<"Certificate corrupted beyond repair: No <------END > tag"<<std::endl;
error_code = RS_PEER_CERT_CLEANING_CODE_NO_END_TAG ;
return badCertificate; return badCertificate;
} }
endCertEndIdx=badCertificate.find(commonTag,endCertStartIdx2); endCertEndIdx=badCertificate.find(commonTag,endCertStartIdx2);
if(endCertEndIdx==std::string::npos || endCertEndIdx>=lengthOfCert) if(endCertEndIdx==std::string::npos || endCertEndIdx>=lengthOfCert)
{ {
std::cerr<<"Certificate corrupted beyond repair: No <------END > tag"<<std::endl; std::cerr<<"Certificate corrupted beyond repair: No <------END > tag"<<std::endl;
error_code = RS_PEER_CERT_CLEANING_CODE_NO_END_TAG ;
return badCertificate; return badCertificate;
} }
/* /*
@ -228,7 +237,7 @@ std::string cleanUpCertificate(const std::string& badCertificate)
{ {
cleanCertificate += badCertificate.substr(currBadCertIdx, (*headerIt).length()); cleanCertificate += badCertificate.substr(currBadCertIdx, (*headerIt).length());
currBadCertIdx += (*headerIt).length(); currBadCertIdx += (*headerIt).length();
while(badCertificate[currBadCertIdx]!='\n') while(currBadCertIdx<endCertStartIdx1 && badCertificate[currBadCertIdx]!='\n')
{ {
cleanCertificate += badCertificate[currBadCertIdx]; cleanCertificate += badCertificate[currBadCertIdx];
currBadCertIdx++; currBadCertIdx++;
@ -250,35 +259,39 @@ std::string cleanUpCertificate(const std::string& badCertificate)
{ {
cleanCertificate += "\n"; cleanCertificate += "\n";
cntPerLine=0; cntPerLine=0;
continue;
} }
else if(badCertificate[currBadCertIdx]=='=')
if(badCertificate[currBadCertIdx]=='=') /* checksum */
{ {
/* checksum */ cntPerLine=0 ;
break; break;
} }
else if(badCertificate[currBadCertIdx]==' ') else if(badCertificate[currBadCertIdx]==' ')
{
currBadCertIdx++; currBadCertIdx++;
continue;
}
else if(badCertificate[currBadCertIdx]=='\n') else if(badCertificate[currBadCertIdx]=='\n')
{
currBadCertIdx++; currBadCertIdx++;
continue; else
{
cleanCertificate += badCertificate[currBadCertIdx];
cntPerLine++;
currBadCertIdx++;
} }
cleanCertificate += badCertificate[currBadCertIdx]; }
cntPerLine++; if(currBadCertIdx>=endCertStartIdx1)
currBadCertIdx++; {
std::cerr<<"Certificate corrupted beyond repair: No checksum, or no newline after first tag"<<std::endl;
error_code = RS_PEER_CERT_CLEANING_CODE_NO_CHECKSUM ;
return badCertificate;
} }
if (badCertificate[currBadCertIdx] == '=') while(currBadCertIdx < endCertStartIdx1 && (badCertificate[currBadCertIdx] == '=' || badCertificate[currBadCertIdx] == ' ' || badCertificate[currBadCertIdx] == '\n' ))
{ currBadCertIdx++ ;
cleanCertificate += "==\n=";
// if (badCertificate[currBadCertIdx] == '=')
// {
/* checksum */ /* checksum */
if (*cleanCertificate.rbegin() != '\n')
{
cleanCertificate += "\n";
}
while(currBadCertIdx<endCertStartIdx1) while(currBadCertIdx<endCertStartIdx1)
{ {
@ -296,7 +309,7 @@ std::string cleanUpCertificate(const std::string& badCertificate)
cntPerLine++; cntPerLine++;
currBadCertIdx++; currBadCertIdx++;
} }
} // }
if(cleanCertificate.substr(cleanCertificate.length()-1,1)!="\n") if(cleanCertificate.substr(cleanCertificate.length()-1,1)!="\n")
{ {
@ -347,6 +360,7 @@ std::string cleanUpCertificate(const std::string& badCertificate)
cleanCertificate += commonTag; cleanCertificate += commonTag;
cleanCertificate += "\n"; cleanCertificate += "\n";
error_code = RS_PEER_CERT_CLEANING_CODE_NO_ERROR ;
return cleanCertificate; return cleanCertificate;
} }

View File

@ -48,6 +48,10 @@
//! //!
//! In the newer gui version, users send each other almost clean certificates, //! In the newer gui version, users send each other almost clean certificates,
//! so this functon is used only to avoid possible bugs with line endings //! so this functon is used only to avoid possible bugs with line endings
std::string cleanUpCertificate(const std::string& badCertificate);
// Error codes (need appropriate message andtranslation in GUI) are listed in rspeers.h
//
std::string cleanUpCertificate(const std::string& badCertificate,int& error_code);
#endif #endif

View File

@ -70,6 +70,13 @@ const uint32_t RS_PEER_CONNECTSTATE_CONNECTED_UDP = 5;
const uint32_t RS_PEER_CONNECTSTATE_CONNECTED_TUNNEL = 6; const uint32_t RS_PEER_CONNECTSTATE_CONNECTED_TUNNEL = 6;
const uint32_t RS_PEER_CONNECTSTATE_CONNECTED_UNKNOWN = 7; const uint32_t RS_PEER_CONNECTSTATE_CONNECTED_UNKNOWN = 7;
/* Error codes for certificate cleaning */
const int RS_PEER_CERT_CLEANING_CODE_NO_ERROR = 0x00 ;
const int RS_PEER_CERT_CLEANING_CODE_UNKOWN_ERROR = 0x01 ;
const int RS_PEER_CERT_CLEANING_CODE_NO_BEGIN_TAG = 0x02 ;
const int RS_PEER_CERT_CLEANING_CODE_NO_END_TAG = 0x03 ;
const int RS_PEER_CERT_CLEANING_CODE_NO_CHECKSUM = 0x04 ;
/* Groups */ /* Groups */
#define RS_GROUP_ID_FRIENDS "Friends" #define RS_GROUP_ID_FRIENDS "Friends"
#define RS_GROUP_ID_FAMILY "Family" #define RS_GROUP_ID_FAMILY "Family"
@ -215,7 +222,7 @@ virtual bool hasExportMinimal() = 0 ;
virtual bool loadCertificateFromFile(const std::string &fname, std::string &ssl_id, std::string &gpg_id) = 0; virtual bool loadCertificateFromFile(const std::string &fname, std::string &ssl_id, std::string &gpg_id) = 0;
virtual bool loadDetailsFromStringCert(const std::string &certGPG, RsPeerDetails &pd,std::string& error_string) = 0; virtual bool loadDetailsFromStringCert(const std::string &certGPG, RsPeerDetails &pd,std::string& error_string) = 0;
virtual bool cleanCertificate(const std::string &certstr, std::string &cleanCert) = 0; virtual bool cleanCertificate(const std::string &certstr, std::string &cleanCert,int& error_code) = 0;
virtual bool saveCertificateToFile(const std::string &id, const std::string &fname) = 0; virtual bool saveCertificateToFile(const std::string &id, const std::string &fname) = 0;
virtual std::string saveCertificateToString(const std::string &id) = 0; virtual std::string saveCertificateToString(const std::string &id) = 0;

View File

@ -1285,13 +1285,13 @@ bool p3Peers::loadDetailsFromStringCert(const std::string &certstr, RsPeerDetai
} }
} }
bool p3Peers::cleanCertificate(const std::string &certstr, std::string &cleanCert) bool p3Peers::cleanCertificate(const std::string &certstr, std::string &cleanCert,int& error_code)
{ {
std::string cert; std::string cert;
std::string peerInfo; std::string peerInfo;
if (splitCert(certstr, cert, peerInfo)) { if (splitCert(certstr, cert, peerInfo)) {
cleanCert = cleanUpCertificate(cert); cleanCert = cleanUpCertificate(cert,error_code);
if (!cleanCert.empty()) { if (!cleanCert.empty()) {
if (!peerInfo.empty()) { if (!peerInfo.empty()) {
if (*cleanCert.rbegin() != '\n') { if (*cleanCert.rbegin() != '\n') {

View File

@ -99,7 +99,7 @@ virtual bool hasExportMinimal() ;
virtual bool loadCertificateFromFile(const std::string &fname, std::string &id, std::string &gpg_id); virtual bool loadCertificateFromFile(const std::string &fname, std::string &id, std::string &gpg_id);
virtual bool loadDetailsFromStringCert(const std::string &cert, RsPeerDetails &pd, std::string& error_string); virtual bool loadDetailsFromStringCert(const std::string &cert, RsPeerDetails &pd, std::string& error_string);
virtual bool cleanCertificate(const std::string &certstr, std::string &cleanCert); virtual bool cleanCertificate(const std::string &certstr, std::string &cleanCert,int& error_code);
virtual bool saveCertificateToFile(const std::string &id, const std::string &fname); virtual bool saveCertificateToFile(const std::string &id, const std::string &fname);
virtual std::string saveCertificateToString(const std::string &id); virtual std::string saveCertificateToString(const std::string &id);

View File

@ -384,10 +384,34 @@ void TextPage::cleanFriendCert()
{ {
std::string cert = friendCertEdit->toPlainText().toUtf8().constData(); std::string cert = friendCertEdit->toPlainText().toUtf8().constData();
std::string cleanCert; std::string cleanCert;
int error_code ;
if (rsPeers->cleanCertificate(cert, cleanCert)) { if (rsPeers->cleanCertificate(cert, cleanCert,error_code)) {
friendCertEdit->setText(QString::fromStdString(cleanCert)); friendCertEdit->setText(QString::fromStdString(cleanCert));
if(error_code > 0)
{
QString msg ;
switch(error_code)
{
case RS_PEER_CERT_CLEANING_CODE_NO_BEGIN_TAG: msg = tr("No or misspelled BEGIN tag found") ;
break ;
case RS_PEER_CERT_CLEANING_CODE_NO_END_TAG: msg = tr("No or misspelled END tag found") ;
break ;
case RS_PEER_CERT_CLEANING_CODE_NO_CHECKSUM: msg = tr("No checksum found (the last 5 chars should be separated by a '=' char), or no newline after tag line (e.g. line beginning with Version:)") ;
break ;
default:
msg = tr("Unknown error. Your cert is probably not even a certificate.") ;
break ;
}
QMessageBox::information(NULL,tr("Certificate cleaning error"),msg) ;
}
} }
QFont font("Courier New",10,50,false);
font.setStyleHint(QFont::TypeWriter,QFont::PreferMatch);
font.setStyle(QFont::StyleNormal);
friendCertEdit->setFont(font);
} }
// //