updated to upstream/master

This commit is contained in:
csoler 2018-01-05 21:59:22 +01:00
commit e28886fe79
79 changed files with 1898 additions and 856 deletions

View file

@ -1403,13 +1403,33 @@ bool DistributedChatService::acceptLobbyInvite(const ChatLobbyId& lobby_id,const
return false;
}
std::map<ChatLobbyId,VisibleChatLobbyRecord>::const_iterator vid = _visible_lobbies.find(lobby_id) ;
if(_visible_lobbies.end() == vid)
{
std::cerr << " (EE) Cannot subscribe a non visible chat lobby!!" << std::endl;
return false ;
}
RsIdentityDetails det ;
if( (!rsIdentity->getIdDetails(identity,det)) || !(det.mFlags & RS_IDENTITY_FLAGS_IS_OWN_ID))
{
std::cerr << " (EE) Cannot subscribe with identity " << identity << " because it is not ours! Something's wrong here." << std::endl;
return false ;
}
if( (vid->second.lobby_flags & RS_CHAT_LOBBY_FLAGS_PGP_SIGNED ) && !(det.mFlags & RS_IDENTITY_FLAGS_PGP_LINKED))
{
std::cerr << " (EE) Cannot subscribe with identity " << identity << " because it is unsigned and the lobby requires signed ids only." << std::endl;
return false ;
}
if(_chat_lobbys.find(lobby_id) != _chat_lobbys.end())
{
std::cerr << " (II) Lobby already exists. Weird." << std::endl;
return true ;
}
#ifdef DEBUG_CHAT_LOBBIES
std::cerr << " Creating new Lobby entry." << std::endl;
#endif
@ -1491,11 +1511,12 @@ void DistributedChatService::denyLobbyInvite(const ChatLobbyId& lobby_id)
bool DistributedChatService::joinVisibleChatLobby(const ChatLobbyId& lobby_id,const RsGxsId& gxs_id)
{
if(!mGixs->isOwnId(gxs_id))
{
std::cerr << "(EE) Cannot lobby using gxs id " << gxs_id << std::endl;
return false ;
}
RsIdentityDetails det ;
if( (!rsIdentity->getIdDetails(gxs_id,det)) || !(det.mFlags & RS_IDENTITY_FLAGS_IS_OWN_ID))
{
std::cerr << " (EE) Cannot subscribe with identity " << gxs_id << " because it is not ours! Something's wrong here." << std::endl;
return false ;
}
#ifdef DEBUG_CHAT_LOBBIES
std::cerr << "Joining public chat lobby " << std::hex << lobby_id << std::dec << std::endl;
@ -1527,6 +1548,12 @@ bool DistributedChatService::joinVisibleChatLobby(const ChatLobbyId& lobby_id,co
return true ;
}
if( (it->second.lobby_flags & RS_CHAT_LOBBY_FLAGS_PGP_SIGNED ) && !(det.mFlags & RS_IDENTITY_FLAGS_PGP_LINKED))
{
std::cerr << " (EE) Cannot subscribe with identity " << gxs_id << " because it is unsigned and the lobby requires signed ids only." << std::endl;
return false ;
}
#ifdef DEBUG_CHAT_LOBBIES
std::cerr << " Creating new lobby entry." << std::endl;
#endif

View file

@ -734,13 +734,39 @@ bool ftController::completeFile(const RsFileHash& hash)
fc->mState = ftFileControl::COMPLETED;
std::string dst_dir,src_dir,src_file,dst_file ;
RsDirUtil::splitDirFromFile(fc->mCurrentPath,src_dir,src_file) ;
RsDirUtil::splitDirFromFile(fc->mDestination,dst_dir,dst_file) ;
// We use this intermediate file in case the destination directory is not available, so as to not keep the partial file name.
std::string intermediate_file_name = src_dir+'/'+dst_file ;
// I don't know how the size can be zero, but believe me, this happens,
// and it causes an error on linux because then the file may not even exist.
//
if( fc->mSize > 0 && RsDirUtil::moveFile(fc->mCurrentPath,fc->mDestination) )
fc->mCurrentPath = fc->mDestination;
else
if( fc->mSize == 0)
fc->mState = ftFileControl::ERROR_COMPLETION;
else
{
std::cerr << "CompleteFile(): renaming " << fc->mCurrentPath << " into " << fc->mDestination << std::endl;
std::cerr << "CompleteFile(): 1 - renaming " << fc->mCurrentPath << " info " << intermediate_file_name << std::endl;
if(RsDirUtil::moveFile(fc->mCurrentPath,intermediate_file_name) )
{
fc->mCurrentPath = intermediate_file_name ;
std::cerr << "CompleteFile(): 2 - renaming/copying " << intermediate_file_name << " into " << fc->mDestination << std::endl;
if(RsDirUtil::moveFile(intermediate_file_name,fc->mDestination) )
fc->mCurrentPath = fc->mDestination;
else
fc->mState = ftFileControl::ERROR_COMPLETION;
}
else
fc->mState = ftFileControl::ERROR_COMPLETION;
}
/* for extralist additions */
path = fc->mDestination;

View file

@ -1382,7 +1382,11 @@ ops_secret_key_t *secret_key = NULL ;
// then do the signature.
ops_boolean_t not_raw = !use_raw_signature ;
ops_memory_t *memres = ops_sign_buf(data,len,(ops_sig_type_t)0x00,secret_key,ops_false,ops_false,not_raw,not_raw) ;
#ifdef V07_NON_BACKWARD_COMPATIBLE_CHANGE_002
ops_memory_t *memres = ops_sign_buf(data,len,OPS_SIG_BINARY,OPS_HASH_SHA256,secret_key,ops_false,ops_false,not_raw,not_raw) ;
#else
ops_memory_t *memres = ops_sign_buf(data,len,OPS_SIG_BINARY,OPS_HASH_SHA1,secret_key,ops_false,ops_false,not_raw,not_raw) ;
#endif
if(!memres)
return false ;
@ -1695,16 +1699,16 @@ bool PGPHandler::mergeKeySignatures(ops_keydata_t *dst,const ops_keydata_t *src)
bool PGPHandler::parseSignature(unsigned char *sign, unsigned int signlen,RsPgpId& issuer_id)
{
uint64_t issuer ;
PGPSignatureInfo info ;
if(!PGPKeyManagement::parseSignature(sign,signlen,issuer))
if(!PGPKeyManagement::parseSignature(sign,signlen,info))
return false ;
unsigned char bytes[8] ;
for(int i=0;i<8;++i)
{
bytes[7-i] = issuer & 0xff ;
issuer >>= 8 ;
bytes[7-i] = info.issuer & 0xff ;
info.issuer >>= 8 ;
}
issuer_id = RsPgpId(bytes) ;

View file

@ -160,7 +160,7 @@ uint32_t PGPKeyManagement::compute24bitsCRC(unsigned char *octets, size_t len)
return crc & 0xFFFFFFL;
}
bool PGPKeyManagement::parseSignature(const unsigned char *signature, size_t sign_len, uint64_t& issuer)
bool PGPKeyManagement::parseSignature(const unsigned char *signature, size_t sign_len, PGPSignatureInfo& info)
{
unsigned char *data = (unsigned char *)signature ;
@ -189,10 +189,10 @@ bool PGPKeyManagement::parseSignature(const unsigned char *signature, size_t sig
if(signature_type != 4)
return false ;
data += 1 ; // skip version number
data += 1 ; // skip signature type
data += 1 ; // skip public key algorithm
data += 1 ; // skip hash algorithm
info.signature_version = data[0] ; data += 1 ; // skip version number
info.signature_type = data[0] ; data += 1 ; // skip signature type
info.public_key_algorithm = data[0] ; data += 1 ; // skip public key algorithm
info.hash_algorithm = data[0] ; data += 1 ; // skip hash algorithm
uint32_t hashed_size = 256u*data[0] + data[1] ;
data += 2 ;
@ -214,7 +214,7 @@ bool PGPKeyManagement::parseSignature(const unsigned char *signature, size_t sig
if(subpacket_type == PGPKeyParser::PGP_PACKET_TAG_ISSUER && subpacket_size == 9)
{
issuer_found = true ;
issuer = PGPKeyParser::read_KeyID(data) ;
info.issuer = PGPKeyParser::read_KeyID(data) ;
}
else
data += subpacket_size-1 ; // we remove the size of subpacket type

View file

@ -41,6 +41,46 @@
#include <stdint.h>
#include <string>
static const uint8_t PGP_PACKET_TAG_HASH_ALGORITHM_UNKNOWN = 0 ;
static const uint8_t PGP_PACKET_TAG_HASH_ALGORITHM_MD5 = 1 ;
static const uint8_t PGP_PACKET_TAG_HASH_ALGORITHM_SHA1 = 2 ;
static const uint8_t PGP_PACKET_TAG_HASH_ALGORITHM_SHA256 = 8 ;
static const uint8_t PGP_PACKET_TAG_HASH_ALGORITHM_SHA512 = 10 ;
static const uint8_t PGP_PACKET_TAG_PUBLIC_KEY_ALGORITHM_UNKNOWN = 0 ;
static const uint8_t PGP_PACKET_TAG_PUBLIC_KEY_ALGORITHM_RSA_ES = 1 ;
static const uint8_t PGP_PACKET_TAG_PUBLIC_KEY_ALGORITHM_RSA_E = 2 ;
static const uint8_t PGP_PACKET_TAG_PUBLIC_KEY_ALGORITHM_RSA_S = 3 ;
static const uint8_t PGP_PACKET_TAG_PUBLIC_KEY_ALGORITHM_DSA = 17 ;
static const uint8_t PGP_PACKET_TAG_SIGNATURE_VERSION_UNKNOWN = 0 ;
static const uint8_t PGP_PACKET_TAG_SIGNATURE_VERSION_V3 = 3 ;
static const uint8_t PGP_PACKET_TAG_SIGNATURE_VERSION_V4 = 4 ;
static const uint8_t PGP_PACKET_TAG_SIGNATURE_TYPE_UNKNOWN = 0xff ;
static const uint8_t PGP_PACKET_TAG_SIGNATURE_TYPE_BINARY_DOCUMENT = 0x00 ;
static const uint8_t PGP_PACKET_TAG_SIGNATURE_TYPE_CANONICAL_TEXT = 0x01 ;
static const uint8_t PGP_PACKET_TAG_SIGNATURE_TYPE_STANDALONE_SIG = 0x02 ;
// All other consts for signature types not used, so not defines.
class PGPSignatureInfo
{
public:
PGPSignatureInfo() :
signature_version (PGP_PACKET_TAG_SIGNATURE_VERSION_UNKNOWN),
signature_type (PGP_PACKET_TAG_SIGNATURE_TYPE_UNKNOWN),
issuer (0),
public_key_algorithm(PGP_PACKET_TAG_PUBLIC_KEY_ALGORITHM_UNKNOWN),
hash_algorithm (PGP_PACKET_TAG_HASH_ALGORITHM_UNKNOWN)
{}
uint8_t signature_version ;
uint8_t signature_type ;
uint64_t issuer ;
uint8_t public_key_algorithm ;
uint8_t hash_algorithm ;
};
// This class handles GPG keys. For now we only clean them from signatures, but
// in the future, we might cache them to avoid unnecessary calls to gpgme.
//
@ -66,7 +106,7 @@ class PGPKeyManagement
//
static uint32_t compute24bitsCRC(unsigned char *data,size_t len) ;
static bool parseSignature(const unsigned char *signature, size_t sign_len, uint64_t &issuer) ;
static bool parseSignature(const unsigned char *signature, size_t sign_len, PGPSignatureInfo& info) ;
};
// This class handles the parsing of PGP packet headers under various (old and new) formats.
@ -74,6 +114,8 @@ class PGPKeyManagement
class PGPKeyParser
{
public:
// These constants correspond to packet tags from RFC4880
static const uint8_t PGP_PACKET_TAG_PUBLIC_KEY = 6 ;
static const uint8_t PGP_PACKET_TAG_USER_ID = 13 ;
static const uint8_t PGP_PACKET_TAG_SIGNATURE = 2 ;

View file

@ -40,9 +40,10 @@
#include "rsitems/rsconfigitems.h"
#include "util/rsdir.h"
#include "util/rsstring.h"
#include "pgp/pgpkeyutil.h"
#include "retroshare/rspeers.h" // for RsPeerDetails structure
#include "retroshare/rsids.h" // for RsPeerDetails structure
#include "retroshare/rsids.h" // for RsPeerDetails structure
#include "rsserver/p3face.h"
/******************** notify of new Cert **************************/
@ -54,13 +55,17 @@
/* SSL connection diagnostic */
const uint32_t RS_SSL_HANDSHAKE_DIAGNOSTIC_UNKNOWN = 0x00 ;
const uint32_t RS_SSL_HANDSHAKE_DIAGNOSTIC_OK = 0x01 ;
const uint32_t RS_SSL_HANDSHAKE_DIAGNOSTIC_CERTIFICATE_NOT_VALID = 0x02 ;
const uint32_t RS_SSL_HANDSHAKE_DIAGNOSTIC_ISSUER_UNKNOWN = 0x03 ;
const uint32_t RS_SSL_HANDSHAKE_DIAGNOSTIC_MALLOC_ERROR = 0x04 ;
const uint32_t RS_SSL_HANDSHAKE_DIAGNOSTIC_WRONG_SIGNATURE = 0x05 ;
const uint32_t RS_SSL_HANDSHAKE_DIAGNOSTIC_CERTIFICATE_MISSING = 0x06 ;
const uint32_t RS_SSL_HANDSHAKE_DIAGNOSTIC_UNKNOWN = 0x00 ;
const uint32_t RS_SSL_HANDSHAKE_DIAGNOSTIC_OK = 0x01 ;
const uint32_t RS_SSL_HANDSHAKE_DIAGNOSTIC_CERTIFICATE_NOT_VALID = 0x02 ;
const uint32_t RS_SSL_HANDSHAKE_DIAGNOSTIC_ISSUER_UNKNOWN = 0x03 ;
const uint32_t RS_SSL_HANDSHAKE_DIAGNOSTIC_MALLOC_ERROR = 0x04 ;
const uint32_t RS_SSL_HANDSHAKE_DIAGNOSTIC_WRONG_SIGNATURE = 0x05 ;
const uint32_t RS_SSL_HANDSHAKE_DIAGNOSTIC_CERTIFICATE_MISSING = 0x06 ;
const uint32_t RS_SSL_HANDSHAKE_DIAGNOSTIC_HASH_ALGORITHM_NOT_ACCEPTED = 0x07 ;
const uint32_t RS_SSL_HANDSHAKE_DIAGNOSTIC_KEY_ALGORITHM_NOT_ACCEPTED = 0x08 ;
const uint32_t RS_SSL_HANDSHAKE_DIAGNOSTIC_WRONG_SIGNATURE_TYPE = 0x09 ;
const uint32_t RS_SSL_HANDSHAKE_DIAGNOSTIC_WRONG_SIGNATURE_VERSION = 0x0a ;
/****
* #define AUTHSSL_DEBUG 1
@ -528,6 +533,7 @@ bool AuthSSLimpl::validateOwnCertificate(X509 *x509, EVP_PKEY *pkey)
/* standard authentication */
if (!AuthX509WithGPG(x509,diagnostic))
{
std::cerr << "Validate Own certificate ERROR: diagnostic = " << diagnostic << std::endl;
return false;
}
return true;
@ -702,7 +708,6 @@ X509 *AuthSSLimpl::SignX509ReqWithGPG(X509_REQ *req, long /*days*/)
#define SERIAL_RAND_BITS 64
//const EVP_MD *digest = EVP_sha1();
ASN1_INTEGER *serial = ASN1_INTEGER_new();
EVP_PKEY *tmppkey;
X509 *x509 = X509_new();
if (x509 == NULL)
@ -727,12 +732,28 @@ X509 *AuthSSLimpl::SignX509ReqWithGPG(X509_REQ *req, long /*days*/)
std::cerr << "AuthSSLimpl::SignX509Req() Issuer name: " << AuthGPG::getAuthGPG()->getGPGOwnId().toStdString() << std::endl;
#ifdef V07_NON_BACKWARD_COMPATIBLE_CHANGE_002
static const uint64_t CERTIFICATE_SERIAL_NUMBER = RS_CERTIFICATE_VERSION_NUMBER_07_0001 ;
#else
#ifdef V07_NON_BACKWARD_COMPATIBLE_CHANGE_001
static const uint64_t CERTIFICATE_SERIAL_NUMBER = RS_CERTIFICATE_VERSION_NUMBER_06_0001 ;
#else
static const uint64_t CERTIFICATE_SERIAL_NUMBER = RS_CERTIFICATE_VERSION_NUMBER_06_0000 ;
#endif
#endif
BIGNUM *btmp = BN_new();
BN_set_word(btmp,CERTIFICATE_SERIAL_NUMBER) ;
#ifdef OLD_CODE
if (!BN_pseudo_rand(btmp, SERIAL_RAND_BITS, 0, 0))
{
std::cerr << "AuthSSLimpl::SignX509Req() rand FAIL" << std::endl;
return NULL;
}
#endif
ASN1_INTEGER *serial = ASN1_INTEGER_new();
if (!BN_to_ASN1_INTEGER(btmp, serial))
{
std::cerr << "AuthSSLimpl::SignX509Req() asn1 FAIL" << std::endl;
@ -763,21 +784,6 @@ X509 *AuthSSLimpl::SignX509ReqWithGPG(X509_REQ *req, long /*days*/)
ASN1_TIME_set(X509_get_notBefore(x509), 0);
ASN1_TIME_set(X509_get_notAfter(x509), 0);
// OLD code, sets validity time of cert to be between now and some days in the future
/*
if (!X509_gmtime_adj(X509_get_notBefore(x509),0))
{
std::cerr << "AuthSSLimpl::SignX509Req() notbefore FAIL" << std::endl;
return NULL;
}
if (!X509_gmtime_adj(X509_get_notAfter(x509), (long)60*60*24*days))
{
std::cerr << "AuthSSLimpl::SignX509Req() notafter FAIL" << std::endl;
return NULL;
}
*/
if (!X509_set_subject_name(x509, X509_REQ_get_subject_name(req)))
{
std::cerr << "AuthSSLimpl::SignX509Req() sub FAIL" << std::endl;
@ -815,11 +821,14 @@ X509 *AuthSSLimpl::SignX509ReqWithGPG(X509_REQ *req, long /*days*/)
ASN1_BIT_STRING *signature = const_cast<ASN1_BIT_STRING*>(tmp_signature);
#endif
//EVP_PKEY *pkey = NULL;
#ifdef V07_NON_BACKWARD_COMPATIBLE_CHANGE_002
const EVP_MD *type = EVP_sha256();
#else
const EVP_MD *type = EVP_sha1();
#endif
EVP_MD_CTX *ctx = EVP_MD_CTX_create();
int inl=0,hashoutl=0;
int sigoutl=0;
int inl=0;
X509_ALGOR *a;
/* FIX ALGORITHMS */
@ -851,48 +860,66 @@ X509 *AuthSSLimpl::SignX509ReqWithGPG(X509_REQ *req, long /*days*/)
std::cerr << "Algorithms Fixed" << std::endl;
unsigned int sigoutl=2048; // hashoutl; //EVP_PKEY_size(pkey);
unsigned char *buf_sigout=(unsigned char *)OPENSSL_malloc((unsigned int)sigoutl);
/* input buffer */
#if OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER)
inl=i2d(data,NULL);
unsigned char *buf_in=(unsigned char *)OPENSSL_malloc((unsigned int)inl);
unsigned char *p=NULL;
if(buf_in == NULL)
{
sigoutl=0;
fprintf(stderr, "AuthSSLimpl::SignX509Req: ASN1err(ASN1_F_ASN1_SIGN,ERR_R_MALLOC_FAILURE)\n");
return NULL ;
}
unsigned char *p=buf_in; // This because i2d modifies the pointer after writing to it.
i2d(data,&p);
#else
unsigned char *buf_in=NULL;
inl=i2d_re_X509_tbs(x509,&buf_in) ; // this does the i2d over x509->cert_info
#endif
hashoutl=EVP_MD_size(type);
unsigned char *buf_hashout=(unsigned char *)OPENSSL_malloc((unsigned int)hashoutl);
sigoutl=2048; // hashoutl; //EVP_PKEY_size(pkey);
unsigned char *buf_sigout=(unsigned char *)OPENSSL_malloc((unsigned int)sigoutl);
if ((buf_in == NULL) || (buf_hashout == NULL) || (buf_sigout == NULL))
{
hashoutl=0;
sigoutl=0;
fprintf(stderr, "AuthSSLimpl::SignX509Req: ASN1err(ASN1_F_ASN1_SIGN,ERR_R_MALLOC_FAILURE)\n");
goto err;
}
#ifdef V07_NON_BACKWARD_COMPATIBLE_CHANGE_003
if((buf_in == NULL) || (buf_sigout == NULL))
{
sigoutl=0;
fprintf(stderr, "AuthSSLimpl::SignX509Req: ASN1err(ASN1_F_ASN1_SIGN,ERR_R_MALLOC_FAILURE)\n");
goto err;
}
std::cerr << "Buffers Allocated" << std::endl;
#if OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER)
p=buf_in;
i2d(data,&p);
#endif
/* NOW Sign via GPG Functions */
if (!AuthGPG::getAuthGPG()->SignDataBin(buf_in, inl, buf_sigout, (unsigned int *) &sigoutl,"AuthSSLimpl::SignX509ReqWithGPG()"))
{
sigoutl = 0;
goto err;
}
#else
unsigned int hashoutl=EVP_MD_size(type);
unsigned char *buf_hashout=(unsigned char *)OPENSSL_malloc((unsigned int)hashoutl);
if((buf_hashout == NULL) || (buf_sigout == NULL))
{
hashoutl=0;
sigoutl=0;
fprintf(stderr, "AuthSSLimpl::SignX509Req: ASN1err(ASN1_F_ASN1_SIGN,ERR_R_MALLOC_FAILURE)\n");
goto err;
}
std::cerr << "Buffers Allocated" << std::endl;
/* data in buf_in, ready to be hashed */
EVP_DigestInit_ex(ctx,type, NULL);
EVP_DigestUpdate(ctx,(unsigned char *)buf_in,inl);
if (!EVP_DigestFinal(ctx,(unsigned char *)buf_hashout,
(unsigned int *)&hashoutl))
{
hashoutl=0;
fprintf(stderr, "AuthSSLimpl::SignX509Req: ASN1err(ASN1_F_ASN1_SIGN,ERR_R_EVP_LIB)\n");
goto err;
}
if (!EVP_DigestFinal(ctx,(unsigned char *)buf_hashout, (unsigned int *)&hashoutl))
{
hashoutl=0;
fprintf(stderr, "AuthSSLimpl::SignX509Req: ASN1err(ASN1_F_ASN1_SIGN,ERR_R_EVP_LIB)\n");
goto err;
}
std::cerr << "Digest Applied: len: " << hashoutl << std::endl;
std::cerr << "Digest Applied: len: " << hashoutl << std::endl;
/* NOW Sign via GPG Functions */
if (!AuthGPG::getAuthGPG()->SignDataBin(buf_hashout, hashoutl, buf_sigout, (unsigned int *) &sigoutl,"AuthSSLimpl::SignX509ReqWithGPG()"))
@ -900,9 +927,12 @@ X509 *AuthSSLimpl::SignX509ReqWithGPG(X509_REQ *req, long /*days*/)
sigoutl = 0;
goto err;
}
#endif
std::cerr << "Buffer Sizes: in: " << inl;
#ifndef V07_NON_BACKWARD_COMPATIBLE_CHANGE_003
std::cerr << " HashOut: " << hashoutl;
#endif
std::cerr << " SigOut: " << sigoutl;
std::cerr << std::endl;
@ -926,6 +956,13 @@ X509 *AuthSSLimpl::SignX509ReqWithGPG(X509_REQ *req, long /*days*/)
EVP_MD_CTX_destroy(ctx) ;
// debug
// {
// int pkey_nid = OBJ_obj2nid(x509->sig_alg->algorithm);
// const char* sslbuf = OBJ_nid2ln(pkey_nid);
// std::cerr << "Signature hash algorithm: " << sslbuf << std::endl;
// }
return x509;
/* XXX CLEANUP */
@ -933,8 +970,10 @@ X509 *AuthSSLimpl::SignX509ReqWithGPG(X509_REQ *req, long /*days*/)
/* cleanup */
if(buf_in != NULL)
OPENSSL_free(buf_in) ;
#ifndef V07_NON_BACKWARD_COMPATIBLE_CHANGE_003
if(buf_hashout != NULL)
OPENSSL_free(buf_hashout) ;
#endif
if(buf_sigout != NULL)
OPENSSL_free(buf_sigout) ;
std::cerr << "GPGAuthMgr::SignX509Req() err: FAIL" << std::endl;
@ -992,12 +1031,13 @@ bool AuthSSLimpl::AuthX509WithGPG(X509 *x509,uint32_t& diagnostic)
X509_get0_signature(&signature,&algor2,x509);
#endif
const EVP_MD *type = EVP_sha1();
uint32_t certificate_version = getX509RetroshareCertificateVersion(x509) ;
EVP_MD_CTX *ctx = EVP_MD_CTX_create();
int inl=0,hashoutl=0;
int sigoutl=0;
int inl=0;
const unsigned char *signed_data = NULL ;
uint32_t signed_data_length =0;
/* input buffer */
#if OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER)
@ -1009,25 +1049,12 @@ bool AuthSSLimpl::AuthX509WithGPG(X509 *x509,uint32_t& diagnostic)
inl=i2d_re_X509_tbs(x509,&buf_in) ; // this does the i2d over x509->cert_info
#endif
hashoutl=EVP_MD_size(type);
unsigned char *buf_hashout=(unsigned char *)OPENSSL_malloc((unsigned int)hashoutl);
sigoutl=2048; //hashoutl; //EVP_PKEY_size(pkey);
unsigned char *buf_sigout=(unsigned char *)OPENSSL_malloc((unsigned int)sigoutl);
#ifdef AUTHSSL_DEBUG
std::cerr << "Buffer Sizes: in: " << inl;
std::cerr << " HashOut: " << hashoutl;
std::cerr << " SigOut: " << sigoutl;
std::cerr << std::endl;
#endif
if ((buf_in == NULL) || (buf_hashout == NULL) || (buf_sigout == NULL)) {
hashoutl=0;
sigoutl=0;
if(buf_in == NULL)
{
fprintf(stderr, "AuthSSLimpl::AuthX509: ASN1err(ASN1_F_ASN1_SIGN,ERR_R_MALLOC_FAILURE)\n");
diagnostic = RS_SSL_HANDSHAKE_DIAGNOSTIC_MALLOC_ERROR ;
goto err;
return false ;
}
#ifdef AUTHSSL_DEBUG
@ -1038,44 +1065,106 @@ bool AuthSSLimpl::AuthX509WithGPG(X509 *x509,uint32_t& diagnostic)
p=buf_in;
i2d(data,&p);
#endif
/* data in buf_in, ready to be hashed */
EVP_DigestInit_ex(ctx,type, NULL);
EVP_DigestUpdate(ctx,(unsigned char *)buf_in,inl);
if (!EVP_DigestFinal(ctx,(unsigned char *)buf_hashout,
(unsigned int *)&hashoutl))
{
hashoutl=0;
fprintf(stderr, "AuthSSLimpl::AuthX509: ASN1err(ASN1_F_ASN1_SIGN,ERR_R_EVP_LIB)\n");
diagnostic = RS_SSL_HANDSHAKE_DIAGNOSTIC_MALLOC_ERROR ;
goto err;
}
{ // this scope is to avoid cross-initialization jumps to err.
const Sha1CheckSum sha1 = RsDirUtil::sha1sum(buf_in,inl) ; // olds the memory until destruction
if(certificate_version < RS_CERTIFICATE_VERSION_NUMBER_07_0001)
{
// If the certificate belongs to 0.6 version, we hash it here, and then re-hash the hash it in the PGP signature.
signed_data = sha1.toByteArray() ;
signed_data_length = sha1.SIZE_IN_BYTES;
}
else
{
signed_data = buf_in ;
signed_data_length = inl ;
}
/* NOW check sign via GPG Functions */
//get the fingerprint of the key that is supposed to sign
#ifdef AUTHSSL_DEBUG
std::cerr << "Digest Applied: len: " << hashoutl << std::endl;
std::cerr << "AuthSSLimpl::AuthX509() verifying the gpg sig with keyprint : " << pd.fpr << std::endl;
std::cerr << "Sigoutl = " << sigoutl << std::endl ;
std::cerr << "pd.fpr = " << pd.fpr << std::endl ;
#endif
/* copy data into signature */
if(sigoutl < signature->length)
{
diagnostic = RS_SSL_HANDSHAKE_DIAGNOSTIC_MALLOC_ERROR ;
goto err;
}
sigoutl = signature->length;
memmove(buf_sigout, signature->data, sigoutl);
// Take a early look at signature parameters. In particular we dont accept signatures with unsecure hash algorithms.
/* NOW check sign via GPG Functions */
//get the fingerprint of the key that is supposed to sign
#ifdef AUTHSSL_DEBUG
std::cerr << "AuthSSLimpl::AuthX509() verifying the gpg sig with keyprint : " << pd.fpr << std::endl;
std::cerr << "Sigoutl = " << sigoutl << std::endl ;
std::cerr << "pd.fpr = " << pd.fpr << std::endl ;
std::cerr << "hashoutl = " << hashoutl << std::endl ;
#endif
PGPSignatureInfo signature_info ;
PGPKeyManagement::parseSignature(signature->data,signature->length,signature_info) ;
if (!AuthGPG::getAuthGPG()->VerifySignBin(buf_hashout, hashoutl, buf_sigout, (unsigned int) sigoutl, pd.fpr)) {
sigoutl = 0;
diagnostic = RS_SSL_HANDSHAKE_DIAGNOSTIC_WRONG_SIGNATURE ;
goto err;
if(signature_info.signature_version != PGP_PACKET_TAG_SIGNATURE_VERSION_V4)
{
diagnostic = RS_SSL_HANDSHAKE_DIAGNOSTIC_WRONG_SIGNATURE_VERSION ;
goto err ;
}
std::string sigtypestring ;
switch(signature_info.signature_type)
{
case PGP_PACKET_TAG_SIGNATURE_TYPE_BINARY_DOCUMENT :
break ;
case PGP_PACKET_TAG_SIGNATURE_TYPE_STANDALONE_SIG :
case PGP_PACKET_TAG_SIGNATURE_TYPE_CANONICAL_TEXT :
case PGP_PACKET_TAG_SIGNATURE_TYPE_UNKNOWN :
default:
diagnostic = RS_SSL_HANDSHAKE_DIAGNOSTIC_WRONG_SIGNATURE_TYPE ;
goto err ;
}
switch(signature_info.public_key_algorithm)
{
case PGP_PACKET_TAG_PUBLIC_KEY_ALGORITHM_RSA_ES :
case PGP_PACKET_TAG_PUBLIC_KEY_ALGORITHM_RSA_S : sigtypestring = "RSA" ;
break ;
case PGP_PACKET_TAG_PUBLIC_KEY_ALGORITHM_DSA : sigtypestring = "DSA" ;
break ;
case PGP_PACKET_TAG_PUBLIC_KEY_ALGORITHM_RSA_E :
case PGP_PACKET_TAG_PUBLIC_KEY_ALGORITHM_UNKNOWN:
default:
diagnostic = RS_SSL_HANDSHAKE_DIAGNOSTIC_HASH_ALGORITHM_NOT_ACCEPTED ;
goto err ;
}
switch(signature_info.hash_algorithm)
{
case PGP_PACKET_TAG_HASH_ALGORITHM_SHA1 : sigtypestring += "+SHA1" ; break;
case PGP_PACKET_TAG_HASH_ALGORITHM_SHA256: sigtypestring += "+SHA256" ; break;
case PGP_PACKET_TAG_HASH_ALGORITHM_SHA512: sigtypestring += "+SHA512" ; break;
// We dont accept signatures with unknown or week hash algorithms.
case PGP_PACKET_TAG_HASH_ALGORITHM_MD5:
case PGP_PACKET_TAG_HASH_ALGORITHM_UNKNOWN:
default:
diagnostic = RS_SSL_HANDSHAKE_DIAGNOSTIC_HASH_ALGORITHM_NOT_ACCEPTED ;
goto err ;
}
// passed, verify the signature itself
if (!AuthGPG::getAuthGPG()->VerifySignBin(signed_data, signed_data_length, signature->data, signature->length, pd.fpr))
{
diagnostic = RS_SSL_HANDSHAKE_DIAGNOSTIC_WRONG_SIGNATURE ;
goto err;
}
RsPeerId peerIdstr ;
getX509id(x509, peerIdstr) ;
std::string fpr = pd.fpr.toStdString();
std::cerr << "Verified " << sigtypestring << " signature of certificate " << peerIdstr << ", Version " << std::hex << certificate_version
<< std::dec << " using PGP key " ;
for(uint32_t i=0;i<fpr.length();i+=4)
std::cerr << fpr.substr(i,4) << " " ;
std::cerr << std::endl;
}
#ifdef AUTHSSL_DEBUG
@ -1084,8 +1173,6 @@ bool AuthSSLimpl::AuthX509WithGPG(X509 *x509,uint32_t& diagnostic)
EVP_MD_CTX_destroy(ctx) ;
OPENSSL_free(buf_in) ;
OPENSSL_free(buf_hashout) ;
OPENSSL_free(buf_sigout) ;
diagnostic = RS_SSL_HANDSHAKE_DIAGNOSTIC_OK ;
@ -1096,10 +1183,7 @@ err:
if(buf_in != NULL)
OPENSSL_free(buf_in) ;
if(buf_hashout != NULL)
OPENSSL_free(buf_hashout) ;
if(buf_sigout != NULL)
OPENSSL_free(buf_sigout) ;
return false;
}

View file

@ -519,6 +519,25 @@ uint32_t p3PeerMgrIMPL::getHiddenType(const RsPeerId &ssl_id)
return (it->second).hiddenType;
}
bool p3PeerMgrIMPL::isHiddenNode(const RsPeerId& id)
{
RsStackMutex stack(mPeerMtx); /****** STACK LOCK MUTEX *******/
if (id == AuthSSL::getAuthSSL()->OwnId())
return mOwnState.hiddenNode ;
else
{
std::map<RsPeerId,peerState>::const_iterator it = mFriendList.find(id);
if (it == mFriendList.end())
{
std::cerr << "p3PeerMgrIMPL::isHiddenNode() Peer Not Found" << std::endl;
return false;
}
return it->second.hiddenNode ;
}
}
/**
* @brief sets hidden domain and port for a given ssl ID
* @param ssl_id peer to set domain and port for
@ -1632,6 +1651,8 @@ bool p3PeerMgrIMPL::updateAddressList(const RsPeerId& id, const pqiIpAddrSet
cleanIpList(clean_set.mExt.mAddrs,id,mLinkMgr) ;
cleanIpList(clean_set.mLocal.mAddrs,id,mLinkMgr) ;
bool am_I_a_hidden_node = isHiddenNode(getOwnId()) ;
RsStackMutex stack(mPeerMtx); /****** STACK LOCK MUTEX *******/
/* check if it is our own ip */
@ -1655,7 +1676,12 @@ bool p3PeerMgrIMPL::updateAddressList(const RsPeerId& id, const pqiIpAddrSet
}
/* "it" points to peer */
it->second.ipAddrs.updateAddrs(clean_set);
if(!am_I_a_hidden_node)
it->second.ipAddrs.updateAddrs(clean_set);
else
it->second.ipAddrs.clear();
#ifdef PEER_DEBUG
std::cerr << "p3PeerMgrIMPL::setLocalAddress() Updated Address for: " << id;
std::cerr << std::endl;
@ -2173,6 +2199,7 @@ bool p3PeerMgrIMPL::loadList(std::list<RsItem *>& load)
#endif
RsPeerId ownId = getOwnId();
bool am_I_a_hidden_node = isHiddenNode(ownId) ;
/* load the list of peers */
std::list<RsItem *>::iterator it;
@ -2220,16 +2247,20 @@ bool p3PeerMgrIMPL::loadList(std::list<RsItem *>& load)
}
else
{
setLocalAddress(peer_id, pitem->localAddrV4.addr);
setExtAddress(peer_id, pitem->extAddrV4.addr);
setDynDNS (peer_id, pitem->dyndns);
/* convert addresses */
pqiIpAddrSet addrs;
addrs.mLocal.extractFromTlv(pitem->localAddrList);
addrs.mExt.extractFromTlv(pitem->extAddrList);
updateAddressList(peer_id, addrs);
if(!am_I_a_hidden_node) // clear IPs if w're a hidden node. Friend's clear node IPs where previously sent.
{
setLocalAddress(peer_id, pitem->localAddrV4.addr);
setExtAddress(peer_id, pitem->extAddrV4.addr);
setDynDNS (peer_id, pitem->dyndns);
/* convert addresses */
addrs.mLocal.extractFromTlv(pitem->localAddrList);
addrs.mExt.extractFromTlv(pitem->extAddrList);
}
updateAddressList(peer_id, addrs);
}
delete(*it);

View file

@ -171,6 +171,7 @@ virtual bool setVisState(const RsPeerId &id, uint16_t vs_disc, uint16_t vs_dht)
virtual bool setLocation(const RsPeerId &pid, const std::string &location) = 0;
virtual bool setHiddenDomainPort(const RsPeerId &id, const std::string &domain_addr, const uint16_t domain_port) = 0;
virtual bool isHiddenNode(const RsPeerId& id) = 0 ;
virtual bool updateCurrentAddress(const RsPeerId& id, const pqiIpAddress &addr) = 0;
virtual bool updateLastContact(const RsPeerId& id) = 0;
@ -284,6 +285,7 @@ public:
virtual bool setLocation(const RsPeerId &pid, const std::string &location);
virtual bool setHiddenDomainPort(const RsPeerId &id, const std::string &domain_addr, const uint16_t domain_port);
virtual bool isHiddenNode(const RsPeerId& id);
virtual bool updateCurrentAddress(const RsPeerId& id, const pqiIpAddress &addr);
virtual bool updateLastContact(const RsPeerId& id);

View file

@ -68,6 +68,12 @@ class pqiIpAddrSet
void printAddrs(std::string &out) const;
pqiIpAddrList mLocal;
pqiIpAddrList mExt;
void clear()
{
mLocal.mAddrs.clear();
mExt.mAddrs.clear();
}
};

0
libretroshare/src/pqi/pqisslproxy.cc Executable file → Normal file
View file

0
libretroshare/src/pqi/pqisslproxy.h Executable file → Normal file
View file

View file

@ -610,31 +610,53 @@ bool getX509id(X509 *x509, RsPeerId& xid)
X509_get0_signature(&signature,&algor,x509);
#endif
int signlen = ASN1_STRING_length(signature);
if (signlen < CERTSIGNLEN)
uint32_t version_number = getX509RetroshareCertificateVersion(x509) ;
if(version_number >= RS_CERTIFICATE_VERSION_NUMBER_06_0001)
{
#ifdef AUTHSSL_DEBUG
std::cerr << "AuthSSL::getX509id() ERROR: Short Signature";
std::cerr << std::endl;
#endif
return false;
// What: Computes the node id by performing a sha256 hash of the certificate's PGP signature, instead of simply picking up the last 20 bytes of it.
//
// Why: There is no real risk in forging a certificate with the same ID as the authentication is performed over the PGP signature of the certificate
// which hashes the full SSL certificate (i.e. the full serialized CERT_INFO structure). However the possibility to
// create two certificates with the same IDs is a problem, as it can be used to cause disturbance in the software.
//
// Backward compat: makes connexions impossible with non patched peers, probably because the SSL id that is computed is not the same on both side,
// and in particular unpatched peers see a cerficate with ID different (because computed with the old method) than the ID that was
// submitted when making friends.
//
// Note: the advantage of basing the ID on the signature rather than the public key is not very clear, given that the signature is based on a hash
// of the public key (and the rest of the certificate info).
//
if(RsPeerId::SIZE_IN_BYTES > Sha256CheckSum::SIZE_IN_BYTES)
return false ;
xid = RsPeerId(RsDirUtil::sha256sum(ASN1_STRING_data(const_cast<ASN1_BIT_STRING*>(signature)),ASN1_STRING_length(signature)).toByteArray()) ;
}
else
{
int signlen = ASN1_STRING_length(signature);
if (signlen < CERTSIGNLEN)
{
#ifdef AUTHSSL_DEBUG
std::cerr << "AuthSSL::getX509id() ERROR: Short Signature";
std::cerr << std::endl;
#endif
return false;
}
// else copy in the first CERTSIGNLEN.
unsigned char *signdata = ASN1_STRING_data(const_cast<ASN1_BIT_STRING*>(signature));
// else copy in the first CERTSIGNLEN.
unsigned char *signdata = ASN1_STRING_data(const_cast<ASN1_BIT_STRING*>(signature));
/* switched to the other end of the signature. for
* more randomness
*/
/* switched to the other end of the signature. for
* more randomness
*/
#warning csoler 2017-02-19: This is cryptographically horrible. We should do a hash of the public key here!!!
#warning csoler 2017-02-19: This is cryptographically horrible. We should hash the entire signature here!
xid = RsPeerId(&signdata[signlen - CERTSIGNLEN]) ;
//for(int i = signlen - CERTSIGNLEN; i < signlen; i++)
//{
// rs_sprintf_append(xid, "%02x", (uint16_t) (((uint8_t *) (signdata))[i]));
//}
xid = RsPeerId(&signdata[signlen - CERTSIGNLEN]) ;
}
return true;
}
@ -663,6 +685,34 @@ bool CheckX509Certificate(X509 */*x509*/)
return true;
}
uint64_t getX509SerialNumber(X509 *cert)
{
ASN1_INTEGER *serial = X509_get_serialNumber(cert);
BIGNUM *btmp = ASN1_INTEGER_to_BN(serial, NULL);
uint64_t res = BN_get_word(btmp) ;
BN_free(btmp);
return res ;
}
uint32_t getX509RetroshareCertificateVersion(X509 *cert)
{
// Because the serial number was totally random before being used to identity the handshake protocol, we check if we see known version strings. If not,
// we assume v0.6-0000
//
// We compare the uint32_t into a uint64_t on purpose,to make sure that the highest bits are 0 and not random.
switch(getX509SerialNumber(cert))
{
case uint64_t(RS_CERTIFICATE_VERSION_NUMBER_06_0000): return RS_CERTIFICATE_VERSION_NUMBER_06_0000 ;
case uint64_t(RS_CERTIFICATE_VERSION_NUMBER_06_0001): return RS_CERTIFICATE_VERSION_NUMBER_06_0001 ;
case uint64_t(RS_CERTIFICATE_VERSION_NUMBER_07_0001): return RS_CERTIFICATE_VERSION_NUMBER_07_0001 ;
default:
return RS_CERTIFICATE_VERSION_NUMBER_06_0000;
}
}
// Not dependent on sslroot. load, and detroys the X509 memory.
int LoadCheckX509(const char *cert_file, RsPgpId& issuerName, std::string &location, RsPeerId &userId)

View file

@ -61,7 +61,15 @@ int EVP_CIPHER_CTX_rand_key(EVP_CIPHER_CTX *ctx, unsigned char *key);
#endif
// Certificates serial number is used to store the protocol version for the handshake. (*) means current version.
//
// 06_0000: < Nov.2017.
// * 06_0001: > Nov 2017. SSL id is computed by hashing the entire signature of the cert instead of simply picking up the last bytes.
// 07_0001: Signatures are performed using SHA256+RSA instead of SHA1+RSA
static const uint32_t RS_CERTIFICATE_VERSION_NUMBER_06_0000 = 0x00060000 ; // means version RS-0.6, certificate version 0. Default version before patch.
static const uint32_t RS_CERTIFICATE_VERSION_NUMBER_06_0001 = 0x00060001 ; // means version RS-0.6, certificate version 1.
static const uint32_t RS_CERTIFICATE_VERSION_NUMBER_07_0001 = 0x00070001 ; // means version RS-0.7, certificate version 1.
X509_REQ *GenerateX509Req(
std::string pkey_file, std::string passwd,
@ -122,6 +130,9 @@ std::string getX509OrgString(X509_NAME *name);
std::string getX509CountryString(X509_NAME *name);
std::string getX509Info(X509 *cert);
uint64_t getX509SerialNumber(X509 *cert);
uint32_t getX509RetroshareCertificateVersion(X509 *cert) ;
/********** SSL ERROR STUFF ******************************************/
int printSSLError(SSL *ssl, int retval, int err, unsigned long err2, std::string &out);

View file

@ -28,6 +28,7 @@
#include <string>
#include <list>
#include <stdint.h>
#include "util/rsprint.h"
#include "retroshare/rstypes.h"
/******************************************************************************************
@ -85,7 +86,9 @@ public:
EXPR_SIZE_MB = 8 } token ;
static Expression *toExpr(const LinearizedExpression& e) ;
std::string GetStrings();
private:
static Expression *toExpr(const LinearizedExpression& e,int&,int&,int&) ;
static void readStringExpr(const LinearizedExpression& e,int& n_ints,int& n_strings,std::list<std::string>& strings,bool& b,StringOperator& op) ;
@ -127,6 +130,7 @@ public:
virtual ~Expression() {};
virtual void linearize(LinearizedExpression& e) const = 0 ;
virtual std::string toStdString() const = 0 ;
};
class CompoundExpression : public Expression
@ -155,6 +159,18 @@ public:
delete Rexp;
}
virtual std::string toStdString() const
{
switch(Op)
{
case AndOp: return "(" + Lexp->toStdString() + ") AND (" + Rexp->toStdString() +")" ;
case OrOp: return "(" + Lexp->toStdString() + ") OR (" + Rexp->toStdString() +")" ;
case XorOp: return "(" + Lexp->toStdString() + ") XOR (" + Rexp->toStdString() +")" ;
default:
return "" ;
}
}
virtual void linearize(LinearizedExpression& e) const ;
private:
Expression *Lexp;
@ -169,6 +185,7 @@ public:
StringExpression(enum StringOperator op, std::list<std::string> &t, bool ic): Op(op),terms(t), IgnoreCase(ic){}
virtual void linearize(LinearizedExpression& e) const ;
virtual std::string toStdString(const std::string& varstr) const;
protected:
bool evalStr(const std::string &str);
@ -184,6 +201,7 @@ public:
RelExpression(enum RelOperator op, T lv, T hv): Op(op), LowerValue(lv), HigherValue(hv) {}
virtual void linearize(LinearizedExpression& e) const ;
virtual std::string toStdString(const std::string& typestr) const;
protected:
bool evalRel(T val);
@ -214,6 +232,22 @@ bool RelExpression<T>::evalRel(T val) {
}
}
template <class T>
std::string RelExpression<T>::toStdString(const std::string& typestr) const
{
std::string LowerValueStr = RsUtil::NumberToString(LowerValue) ;
switch (Op) {
case Equals: return typestr + " = " + LowerValueStr ;
case GreaterEquals: return typestr + " <= "+ LowerValueStr ;
case Greater: return typestr + " < " + LowerValueStr ;
case SmallerEquals: return typestr + " >= "+ LowerValueStr ;
case Smaller: return typestr + " > " + LowerValueStr ;
case InRange: return LowerValueStr + " <= " + typestr + " <= " + RsUtil::NumberToString(HigherValue) ;
default:
return "";
}
}
/******************************************************************************************
Binary Predicate for Case Insensitive search
@ -245,6 +279,8 @@ public:
StringExpression(op,t,ic) {}
bool eval(const ExpFileEntry& file);
virtual std::string toStdString() const { return StringExpression::toStdString("NAME"); }
virtual void linearize(LinearizedExpression& e) const
{
e._tokens.push_back(LinearizedExpression::EXPR_NAME) ;
@ -258,6 +294,8 @@ public:
StringExpression(op,t,ic) {}
bool eval(const ExpFileEntry& file);
virtual std::string toStdString()const { return StringExpression::toStdString("PATH"); }
virtual void linearize(LinearizedExpression& e) const
{
e._tokens.push_back(LinearizedExpression::EXPR_PATH) ;
@ -271,6 +309,8 @@ public:
StringExpression(op,t,ic) {}
bool eval(const ExpFileEntry& file);
virtual std::string toStdString()const { return StringExpression::toStdString("EXTENSION"); }
virtual void linearize(LinearizedExpression& e) const
{
e._tokens.push_back(LinearizedExpression::EXPR_EXT) ;
@ -284,6 +324,8 @@ public:
StringExpression(op,t, true) {}
bool eval(const ExpFileEntry& file);
virtual std::string toStdString() const { return StringExpression::toStdString("HASH"); }
virtual void linearize(LinearizedExpression& e) const
{
e._tokens.push_back(LinearizedExpression::EXPR_HASH) ;
@ -304,6 +346,8 @@ public:
RelExpression<int>(op,lv,hv) {}
bool eval(const ExpFileEntry& file);
virtual std::string toStdString() const { return RelExpression<int>::toStdString("DATE"); }
virtual void linearize(LinearizedExpression& e) const
{
e._tokens.push_back(LinearizedExpression::EXPR_DATE) ;
@ -319,6 +363,8 @@ public:
RelExpression<int>(op,lv,hv) {}
bool eval(const ExpFileEntry& file);
virtual std::string toStdString() const { return RelExpression<int>::toStdString("SIZE"); }
virtual void linearize(LinearizedExpression& e) const
{
e._tokens.push_back(LinearizedExpression::EXPR_SIZE) ;
@ -334,6 +380,8 @@ public:
RelExpression<int>(op,lv,hv) {}
bool eval(const ExpFileEntry& file);
virtual std::string toStdString() const { return RelExpression<int>::toStdString("SIZE"); }
virtual void linearize(LinearizedExpression& e) const
{
e._tokens.push_back(LinearizedExpression::EXPR_SIZE_MB) ;
@ -348,6 +396,8 @@ public:
PopExpression(const LinearizedExpression& e) ;
bool eval(const ExpFileEntry& file);
virtual std::string toStdString() const { return RelExpression<int>::toStdString("POPULARITY"); }
virtual void linearize(LinearizedExpression& e) const
{
e._tokens.push_back(LinearizedExpression::EXPR_POP) ;

View file

@ -221,6 +221,7 @@ static const int CERT_SIGN_LEN = 16 ; // = CERTSIGNLEN
static const int PGP_KEY_ID_SIZE = 8 ;
static const int PGP_KEY_FINGERPRINT_SIZE = 20 ;
static const int SHA1_SIZE = 20 ;
static const int SHA256_SIZE = 32 ;
// These constants are random, but should be different, in order to make the various IDs incompatible with each other.
//
@ -236,10 +237,12 @@ static const uint32_t RS_GENERIC_ID_GROUTER_ID_TYPE = 0x0009 ;
static const uint32_t RS_GENERIC_ID_GXS_TUNNEL_ID_TYPE = 0x0010 ;
static const uint32_t RS_GENERIC_ID_GXS_DISTANT_CHAT_ID_TYPE = 0x0011 ;
static const uint32_t RS_GENERIC_ID_NODE_GROUP_ID_TYPE = 0x0012 ;
static const uint32_t RS_GENERIC_ID_SHA256_ID_TYPE = 0x0013 ;
typedef t_RsGenericIdType< SSL_ID_SIZE , false, RS_GENERIC_ID_SSL_ID_TYPE> SSLIdType ;
typedef t_RsGenericIdType< PGP_KEY_ID_SIZE , true, RS_GENERIC_ID_PGP_ID_TYPE> PGPIdType ;
typedef t_RsGenericIdType< SHA1_SIZE , false, RS_GENERIC_ID_SHA1_ID_TYPE> Sha1CheckSum ;
typedef t_RsGenericIdType< SHA256_SIZE , false, RS_GENERIC_ID_SHA256_ID_TYPE> Sha256CheckSum ;
typedef t_RsGenericIdType< PGP_KEY_FINGERPRINT_SIZE, true, RS_GENERIC_ID_PGP_FINGERPRINT_TYPE> PGPFingerprintType ;
typedef t_RsGenericIdType< CERT_SIGN_LEN , false, RS_GENERIC_ID_GXS_GROUP_ID_TYPE > GXSGroupId ;

View file

@ -368,6 +368,7 @@ public:
virtual bool setHiddenNode(const RsPeerId &id, const std::string &hidden_node_address) = 0;
virtual bool setHiddenNode(const RsPeerId &id, const std::string &address, uint16_t port) = 0;
virtual bool isHiddenNode(const RsPeerId &id) = 0;
virtual bool setLocalAddress(const RsPeerId &ssl_id, const std::string &addr, uint16_t port) = 0;
virtual bool setExtAddress( const RsPeerId &ssl_id, const std::string &addr, uint16_t port) = 0;

View file

@ -59,6 +59,7 @@ struct TurtleRequestDisplayInfo
RsPeerId source_peer_id ; // Peer that relayed the request
uint32_t age ; // Age in seconds
uint32_t depth ; // Depth of the request. Might be altered.
std::string keywords;
};
class TurtleTrafficStatisticsInfo

View file

@ -882,6 +882,11 @@ bool p3Peers::setHiddenNode(const RsPeerId &id, const std::string &hidden_node_
}
bool p3Peers::isHiddenNode(const RsPeerId &id)
{
return mPeerMgr->isHiddenNode(id) ;
}
bool p3Peers::setHiddenNode(const RsPeerId &id, const std::string &address, uint16_t port)
{
#ifdef P3PEERS_DEBUG

View file

@ -94,6 +94,7 @@ public:
virtual bool setLocation(const RsPeerId &ssl_id, const std::string &location);//location is shown in the gui to differentiate ssl certs
virtual bool setHiddenNode(const RsPeerId &id, const std::string &hidden_node_address);
virtual bool setHiddenNode(const RsPeerId &id, const std::string &address, uint16_t port);
virtual bool isHiddenNode(const RsPeerId &id);
virtual bool setLocalAddress(const RsPeerId &id, const std::string &addr, uint16_t port);
virtual bool setExtAddress(const RsPeerId &id, const std::string &addr, uint16_t port);

View file

@ -38,7 +38,7 @@ RsDisc *rsDisc = NULL;
* #define P3DISC_DEBUG 1
****/
bool populateContactInfo(const peerState &detail, RsDiscContactItem *pkt)
static bool populateContactInfo(const peerState &detail, RsDiscContactItem *pkt,bool include_ip_information)
{
pkt->clear();
@ -62,14 +62,24 @@ bool populateContactInfo(const peerState &detail, RsDiscContactItem *pkt)
{
pkt->isHidden = false;
pkt->localAddrV4.addr = detail.localaddr;
pkt->extAddrV4.addr = detail.serveraddr;
sockaddr_storage_clear(pkt->localAddrV6.addr);
sockaddr_storage_clear(pkt->extAddrV6.addr);
if(include_ip_information)
{
pkt->localAddrV4.addr = detail.localaddr;
pkt->extAddrV4.addr = detail.serveraddr;
sockaddr_storage_clear(pkt->localAddrV6.addr);
sockaddr_storage_clear(pkt->extAddrV6.addr);
pkt->dyndns = detail.dyndns;
detail.ipAddrs.mLocal.loadTlv(pkt->localAddrList);
detail.ipAddrs.mExt.loadTlv(pkt->extAddrList);
pkt->dyndns = detail.dyndns;
detail.ipAddrs.mLocal.loadTlv(pkt->localAddrList);
detail.ipAddrs.mExt.loadTlv(pkt->extAddrList);
}
else
{
sockaddr_storage_clear(pkt->localAddrV6.addr);
sockaddr_storage_clear(pkt->extAddrV6.addr);
sockaddr_storage_clear(pkt->localAddrV4.addr);
sockaddr_storage_clear(pkt->extAddrV4.addr);
}
}
return true;
@ -334,9 +344,8 @@ void p3discovery2::sendOwnContactInfo(const SSLID &sslid)
if (mPeerMgr->getOwnNetStatus(detail))
{
RsDiscContactItem *pkt = new RsDiscContactItem();
populateContactInfo(detail, pkt);
populateContactInfo(detail, pkt, !rsPeers->isHiddenNode(sslid)); // we dont send our own IP to an hidden node. It will not use it anyway.
pkt->version = RsUtil::retroshareVersion();
pkt->PeerId(sslid);
#ifdef P3DISC_DEBUG
@ -372,6 +381,7 @@ void p3discovery2::recvOwnContactInfo(const SSLID &fromId, const RsDiscContactIt
mPeerMgr->setVisState(fromId, item->vs_disc, item->vs_dht);
setPeerVersion(fromId, item->version);
updatePeerAddresses(item);
// This information will be sent out to online peers, at the receipt of their PGPList.
@ -423,13 +433,10 @@ void p3discovery2::recvOwnContactInfo(const SSLID &fromId, const RsDiscContactIt
void p3discovery2::updatePeerAddresses(const RsDiscContactItem *item)
{
if (item->isHidden)
{
mPeerMgr->setHiddenDomainPort(item->sslId, item->hiddenAddr, item->hiddenPort);
}
else
{
mPeerMgr->setDynDNS(item->sslId, item->dyndns);
updatePeerAddressList(item);
}
}
@ -440,7 +447,7 @@ void p3discovery2::updatePeerAddressList(const RsDiscContactItem *item)
if (item->isHidden)
{
}
else
else if(!mPeerMgr->isHiddenNode(rsPeers->getOwnId())) // we don't store IP addresses if we're a hidden node. Normally they should not be sent to us, except for old peers.
{
pqiIpAddrSet addrsFromPeer;
addrsFromPeer.mLocal.extractFromTlv(item->localAddrList);
@ -817,7 +824,7 @@ void p3discovery2::sendContactInfo_locked(const PGPID &aboutId, const SSLID &toI
if (mPeerMgr->getFriendNetStatus(sit->first, detail))
{
RsDiscContactItem *pkt = new RsDiscContactItem();
populateContactInfo(detail, pkt);
populateContactInfo(detail, pkt,!mPeerMgr->isHiddenNode(toId));// never send IPs to an hidden node. The node will not use them anyway.
pkt->PeerId(toId);
// send to each peer its own connection address.

View file

@ -907,6 +907,7 @@ void p3turtle::handleSearchRequest(RsTurtleSearchRequestItem *item)
req.origin = item->PeerId() ;
req.time_stamp = time(NULL) ;
req.depth = item->depth ;
req.keywords = item->GetKeywords() ;
// If it's not for us, perform a local search. If something found, forward the search result back.
@ -1785,6 +1786,10 @@ void RsTurtleRegExpSearchRequestItem::performLocalSearch(std::list<TurtleFileInf
if(exp == NULL)
return ;
#ifdef P3TURTLE_DEBUG
std::cerr << "Local search on exp: " << exp->toStdString() << std::endl;
#endif
// now, search!
rsFiles->SearchBoolExp(exp,initialResults,RS_FILE_HINTS_LOCAL | RS_FILE_HINTS_SEARCHABLE,PeerId());
@ -2097,6 +2102,7 @@ void p3turtle::getInfo( std::vector<std::vector<std::string> >& hashes_info,
info.source_peer_id = it->second.origin ;
info.age = now - it->second.time_stamp ;
info.depth = it->second.depth ;
info.keywords = it->second.keywords ;
search_reqs_info.push_back(info) ;
}

View file

@ -172,6 +172,7 @@ class TurtleRequestInfo
uint32_t time_stamp ; // last time the tunnel was actually used. Used for cleaning old tunnels.
int depth ; // depth of the request. Used to optimize tunnel length.
std::set<uint32_t> responses; // responses to this request. Useful to avoid spamming tunnel responses.
std::string keywords;
};
class TurtleTunnel

View file

@ -71,7 +71,9 @@ class RsTurtleSearchRequestItem: public RsTurtleItem
virtual RsTurtleSearchRequestItem *clone() const = 0 ; // used for cloning in routing methods
virtual void performLocalSearch(std::list<TurtleFileInfo>&) const = 0 ; // abstracts the search method
virtual std::string GetKeywords() = 0;
uint32_t request_id ; // randomly generated request id.
uint16_t depth ; // Used for limiting search depth.
};
@ -82,7 +84,9 @@ class RsTurtleStringSearchRequestItem: public RsTurtleSearchRequestItem
RsTurtleStringSearchRequestItem() : RsTurtleSearchRequestItem(RS_TURTLE_SUBTYPE_STRING_SEARCH_REQUEST) {}
std::string match_string ; // string to match
std::string GetKeywords() { return match_string; }
virtual RsTurtleSearchRequestItem *clone() const { return new RsTurtleStringSearchRequestItem(*this) ; }
virtual void performLocalSearch(std::list<TurtleFileInfo>&) const ;
@ -99,6 +103,14 @@ class RsTurtleRegExpSearchRequestItem: public RsTurtleSearchRequestItem
RsRegularExpression::LinearizedExpression expr ; // Reg Exp in linearised mode
std::string GetKeywords()
{
RsRegularExpression::Expression *ex = RsRegularExpression::LinearizedExpression::toExpr(expr);
std::string exs = ex->toStdString();
delete ex;
return exs;
}
virtual RsTurtleSearchRequestItem *clone() const { return new RsTurtleRegExpSearchRequestItem(*this) ; }
virtual void performLocalSearch(std::list<TurtleFileInfo>&) const ;

View file

@ -104,6 +104,23 @@ const char *RsDirUtil::scanf_string_for_uint(int bytes)
return strgs[0] ;
}
bool RsDirUtil::splitDirFromFile(const std::string& full_path,std::string& dir, std::string& file)
{
int i = full_path.rfind('/', full_path.size()-1);
if(i == full_path.size()-1) // '/' not found!
{
file = full_path ;
dir = "." ;
return true ;
}
dir.assign(full_path,0,i+1) ;
file.assign(full_path,i+1,full_path.size()) ;
return true ;
}
void RsDirUtil::removeTopDir(const std::string& dir, std::string& path)
{
path.clear();
@ -245,6 +262,19 @@ bool RsDirUtil::fileExists(const std::string& filename)
bool RsDirUtil::moveFile(const std::string& source,const std::string& dest)
{
// Check that the destination directory exists. If not, create it.
std::string dest_dir ;
std::string dest_file ;
splitDirFromFile(dest,dest_dir,dest_file) ;
std::cerr << "Moving file " << source << " to " << dest << std::endl;
std::cerr << "Checking that directory " << dest_dir << " actually exists." << std::endl;
if(!checkCreateDirectory(dest_dir))
return false ;
// First try a rename
//
@ -458,7 +488,7 @@ bool RsDirUtil::checkCreateDirectory(const std::string& dir)
std::cerr << "check_create_directory() Fatal Error et oui--";
std::cerr <<std::endl<< "\tcannot create:" <<dir<<std::endl;
#endif
return 0;
return false;
}
#ifdef RSDIR_DEBUG
@ -466,7 +496,7 @@ bool RsDirUtil::checkCreateDirectory(const std::string& dir)
std::cerr <<std::endl<< "\tcreated:" <<dir<<std::endl;
#endif
return 1;
return true;
}
#ifdef RSDIR_DEBUG
@ -480,7 +510,7 @@ bool RsDirUtil::checkCreateDirectory(const std::string& dir)
closedir(direc) ;
#endif
return 1;
return true;
}
@ -610,6 +640,27 @@ Sha1CheckSum RsDirUtil::sha1sum(const unsigned char *data, uint32_t size)
return Sha1CheckSum(sha_buf) ;
}
Sha256CheckSum RsDirUtil::sha256sum(const unsigned char *data, uint32_t size)
{
SHA256_CTX sha_ctx ;
if(SHA256_DIGEST_LENGTH != 32)
throw std::runtime_error("Warning: can't compute Sha2561Sum with sum size != 32") ;
SHA256_Init(&sha_ctx);
while(size > 512)
{
SHA256_Update(&sha_ctx, data, 512);
data = &data[512] ;
size -= 512 ;
}
SHA256_Update(&sha_ctx, data, size);
unsigned char sha_buf[SHA256_DIGEST_LENGTH];
SHA256_Final(&sha_buf[0], &sha_ctx);
return Sha256CheckSum(sha_buf) ;
}
bool RsDirUtil::saveStringToFile(const std::string &file, const std::string &str)
{
std::ofstream out(file.c_str(), std::ios_base::out | std::ios_base::binary);

View file

@ -83,6 +83,11 @@ const char *scanf_string_for_uint(int bytes) ;
int breakupDirList(const std::string& path, std::list<std::string> &subdirs);
// Splits the path into parent directory and file. File can be empty if full_path is a dir ending with '/'
// if full_path does not contain a directory, then dir will be "." and file will be full_path.
bool splitDirFromFile(const std::string& full_path,std::string& dir, std::string& file);
bool copyFile(const std::string& source,const std::string& dest);
bool moveFile(const std::string& source,const std::string& dest);
bool removeFile(const std::string& file);
@ -101,7 +106,8 @@ bool cleanupDirectoryFaster(const std::string& dir, const std::set<std::stri
bool hashFile(const std::string& filepath, std::string &name, RsFileHash &hash, uint64_t &size);
bool getFileHash(const std::string& filepath,RsFileHash &hash, uint64_t &size, RsThread *thread = NULL);
Sha1CheckSum sha1sum(const uint8_t *data,uint32_t size) ;
Sha1CheckSum sha1sum(const uint8_t *data,uint32_t size) ;
Sha256CheckSum sha256sum(const uint8_t *data,uint32_t size) ;
bool saveStringToFile(const std::string& file, const std::string& str);
bool loadStringFromFile(const std::string& file, std::string& str);

View file

@ -128,6 +128,32 @@ static bool StrContains( const std::string & str1, const std::string & str2,
}
std::string StringExpression::toStdString(const std::string& varstr) const
{
std::string strlist ;
for (auto iter = terms.begin(); iter != terms.end(); ++iter )
strlist += *iter + " ";
if(!strlist.empty())
strlist.resize(strlist.size()-1); //strlist.pop_back(); // pops the last ",". c++11 is needed for pop_back()
switch(Op)
{
case ContainsAllStrings: return varstr + " CONTAINS ALL "+strlist ;
case ContainsAnyStrings: if(terms.size() == 1)
return varstr + " CONTAINS "+strlist ;
else
return varstr + " CONTAINS ONE OF "+strlist ;
case EqualsString: if(terms.size() == 1)
return varstr + " IS "+strlist ;
else
return varstr + " IS ONE OF "+strlist ;
default:
return "" ;
}
}
bool StringExpression :: evalStr ( const std::string &str ){
std::list<std::string>::iterator iter;
switch (Op) {
@ -199,6 +225,17 @@ void LinearizedExpression::readStringExpr(const LinearizedExpression& e,int& n_i
strings.push_back(e._strings[n_strings++]) ;
}
std::string LinearizedExpression::GetStrings()
{
std::string str;
for (std::vector<std::string>::const_iterator i = this->_strings.begin(); i != this->_strings.end(); ++i)
{
str += *i;
str += " ";
}
return str;
}
Expression *LinearizedExpression::toExpr(const LinearizedExpression& e,int& n_tok,int& n_ints,int& n_strings)
{
LinearizedExpression::token tok = static_cast<LinearizedExpression::token>(e._tokens[n_tok++]) ;