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

@ -52,7 +52,8 @@ addons:
branch_pattern: coverity_scan branch_pattern: coverity_scan
before_script: before_script:
- qmake QMAKE_CC=$CC QMAKE_CXX=$CXX CONFIG+=no_sqlcipher CONFIG+=tests - if [ $TRAVIS_OS_NAME == linux ]; then qmake QMAKE_CC=$CC QMAKE_CXX=$CXX CONFIG+=no_sqlcipher CONFIG+=tests ; fi
- if [ $TRAVIS_OS_NAME == osx ]; then qmake QMAKE_CC=$CC QMAKE_CXX=$CXX CONFIG+=no_sqlcipher CONFIG+=tests CONFIG+=rs_macos10.12 ; fi
script: script:
- if [ $TRAVIS_OS_NAME == linux ] && [ "${COVERITY_SCAN_BRANCH}" != 1 ]; then make && tests/unittests/unittests >/dev/null 2>&1 ; fi - if [ $TRAVIS_OS_NAME == linux ] && [ "${COVERITY_SCAN_BRANCH}" != 1 ]; then make && tests/unittests/unittests >/dev/null 2>&1 ; fi

View File

@ -106,6 +106,50 @@ To enable enable _protection_: +Android menu -> Settings -> Privacy & security
Other devices may offer similar _features_ please report them. Other devices may offer similar _features_ please report them.
== Debugging with GDB
QtCreator actually support debugging only for the foreground activity, so to
debug what's happening in the core extra trickery is needed.
First of all you need to authorize root access to applications, then once you
plug your sacrifical Android phone run this commands
.Run gdbserver as root on Android phone
[source,bash]
--------------------------------------------------------------------------------
## Open a shell from your workstation on the connected Android phone
adb shell
## take note of the PID of the RetroShare process
ps | grep retroshare
## take the note of the phone IP
ip address show
## Gain root permissions on the shell
su
## Attach with gdbserver and listen on one TCP port
gdbserver :4567 --attach $RETROSHARE_PID
--------------------------------------------------------------------------------
.Prepare and run Android NDK GDB on your workstation
[source,bash]
--------------------------------------------------------------------------------
## Extract system lib from the phone to a temporary directory on your computer
adb pull /system/lib /tmp/system_lib
## Start Android NDK GDB of your phone architecture passing the executable
/opt/android-ndk/toolchains/arm-linux-androideabi-4.9/prebuilt/linux-x86_64/bin/arm-linux-androideabi-gdb RetroShare-Android_for_armeabi_v7a_GCC_4_9_Qt_5_9_2_android_armv7-Debug/retroshare-android-service/src/libretroshare-android-service.so
## Instruct GDB how and where to find libraries
(gdb) set auto-solib-add on
(gdb) set solib-search-path /tmp/system_lib
## Connect to the gdbserver running on the phone
(gdb) target remote $PHONE_IP:4567
--------------------------------------------------------------------------------
== Furter Readings == Furter Readings
@ -115,3 +159,5 @@ Other devices may offer similar _features_ please report them.
- link:retroshare://file?name=Android%20Native%20Development%20Kit%20Cookbook.pdf&size=29214468&hash=0123361c1b14366ce36118e82b90faf7c7b1b136[] - link:retroshare://file?name=Android%20Native%20Development%20Kit%20Cookbook.pdf&size=29214468&hash=0123361c1b14366ce36118e82b90faf7c7b1b136[]
- link:https://groups.google.com/forum/#!topic/android-developers/srATPaL0aRU[] - link:https://groups.google.com/forum/#!topic/android-developers/srATPaL0aRU[]
- link:https://stackoverflow.com/questions/31638986/protected-apps-setting-on-huawei-phones-and-how-to-handle-it[] - link:https://stackoverflow.com/questions/31638986/protected-apps-setting-on-huawei-phones-and-how-to-handle-it[]
- link:https://tthtlc.wordpress.com/2012/09/19/how-to-do-remote-debugging-via-gdbserver-running-inside-the-android-phone/[]
- link:https://source.android.com/devices/tech/debug/gdb[]

View File

@ -1,5 +1,78 @@
retroshare (0.6.3-1.XXXXXX~YYYYYY) YYYYYY; urgency=low retroshare (0.6.3-1.XXXXXX~YYYYYY) YYYYYY; urgency=low
c2d5579 csoler Thu, 21 Dec 2017 17:06:32 +0100 storage of chat room icons in local variables to avoid re-reading them from qrc everytime (patch from sss)
acd8355 Gioacc Wed, 20 Dec 2017 18:24:28 +0100 Add some documentation on how to debug retroshare on android
c0d8333 csoler Mon, 18 Dec 2017 16:10:52 +0100 Merge pull request #1136 from csoler/v0.6-FT
ed0e280 csoler Mon, 18 Dec 2017 16:01:27 +0100 Merge pull request #1135 from PhenomRetroShare/Fix_DontSetMacOsTargetIfNotMacOs
4950ffb Phenom Fri, 15 Dec 2017 10:01:30 +0100 Don't Set Target and SDK if not MacOS
0895b3d csoler Sun, 17 Dec 2017 13:55:50 +0100 Merge pull request #1134 from PhenomRetroShare/Fix_TravisCI_MacOS_Compil
3007fec csoler Sat, 16 Dec 2017 17:46:44 +0100 fixed colors in keyring with new ModelIndex based view (patch from sss)
99e35b1 csoler Sat, 16 Dec 2017 15:04:16 +0100 rename file in partials into real name before moving it; check for destination directory before moving file
a3acd58 Phenom Fri, 8 Dec 2017 19:00:34 +0100 Fix TravisCI on MacOS compilation.
acbcba8 csoler Thu, 7 Dec 2017 17:20:27 +0100 attempt to fix icon sizes in identity dialog
d2c8ba1 csoler Mon, 4 Dec 2017 16:33:45 +0100 Merge pull request #1117 from chelovechishko/qdarkstyle_fix
22292fc csoler Mon, 4 Dec 2017 16:32:37 +0100 Merge pull request #1118 from RetroPooh/net_settings_antifreeze
621ed71 csoler Mon, 4 Dec 2017 16:31:48 +0100 Merge pull request #1120 from sehraf/pr_fixForumDownloadAll
0503f42 csoler Mon, 4 Dec 2017 16:30:29 +0100 Merge pull request #1119 from RetroPooh/chan-fix-cyr
49b4057 sehraf Sat, 2 Dec 2017 15:00:24 +0100 fix 'download all' button for forum. Now all file links are opened in one collection dialog instead of each link in one separate dialog.
98d2772 chelov Sat, 2 Dec 2017 17:10:15 +0900 gui: make forums_dialog slightly more readable sometimes
8ec69df RetroP Wed, 29 Nov 2017 19:23:52 +0300 fix cyrillic text sent wrong in channel post
a88c2ef RetroP Wed, 29 Nov 2017 17:17:49 +0300 fix freezes in network settings
b99a1a5 defnax Tue, 28 Nov 2017 19:36:39 +0100 fixed the emote file for unshown emotes on gui
d1cdba8 Chelov Mon, 27 Nov 2017 14:48:14 +0900 gui: fix probably mistake with names in qdarkstyle.qss
8c34a50 Chelov Mon, 27 Nov 2017 11:16:37 +0900 gui: fix default color of some text in friends list in qdarkstyle.qss
d566a2a Chelov Mon, 27 Nov 2017 10:54:19 +0900 gui: fix keyring background color in qdarkstyle.qss
c05dd30 Chelov Mon, 27 Nov 2017 10:40:24 +0900 gui: fix doubled semicolons in qdarkstyle.qss
63b3acb csoler Thu, 23 Nov 2017 21:27:03 +0100 Merge pull request #1113 from csoler/v0.6-SSL110Fix
1faa274 csoler Wed, 22 Nov 2017 23:46:57 +0100 simplified memory management in certificate signature verification code
669f2ba csoler Wed, 22 Nov 2017 22:56:40 +0100 fixed a few bugs in signature verification code accross versions
c8c90ab csoler Wed, 22 Nov 2017 20:31:49 +0100 Merge pull request #1115 from PhenomRetroShare/Add_CopyComment
f6d69e0 csoler Wed, 22 Nov 2017 00:02:11 +0100 ensured maximum backward compatibility for crypto changes that will occur in future v0.7
6d4c942 Gioacc Tue, 21 Nov 2017 13:28:24 +0100 Removed unnecessary executable flag on some files
49d2366 csoler Tue, 21 Nov 2017 09:29:52 +0100 fixed windows compilation
ea241f6 csoler Tue, 21 Nov 2017 09:27:21 +0100 restored plugins removed by previous commit
d905144 csoler Mon, 20 Nov 2017 23:18:53 +0100 Merge pull request #1114 from PhenomRetroShare/Fix_DisableReplyToSystemMessage
d1d66bb csoler Mon, 20 Nov 2017 23:17:16 +0100 Merge pull request #1079 from csoler/v0.6-Keyring
e2c1661 csoler Mon, 20 Nov 2017 22:44:34 +0100 fixed compilation with v0.7 defines
cd51afb csoler Mon, 20 Nov 2017 22:26:14 +0100 fixed small bug in signature and compilation
9367aa0 csoler Sun, 19 Nov 2017 20:15:36 +0100 changed #ifs into #ifdefs because it us more robust, and moved the definition of variables to retroshare.pri
ef1a613 csoler Sun, 19 Nov 2017 19:57:38 +0100 added proper debug output for signature verification
863e625 csoler Sun, 19 Nov 2017 19:34:54 +0100 centralized the defines into a single file
e72bd9f csoler Sun, 19 Nov 2017 18:38:46 +0100 fixed bug causing certificate rejection
b4fdd4e csoler Sun, 19 Nov 2017 18:21:56 +0100 added two additional non packward compatible changes for future version 0.7, and improvements of verifications of certificate signatures
46a6bdc Phenom Sat, 18 Nov 2017 19:48:38 +0100 Add Copy action for Gxs Comments.
71efb9f Phenom Sat, 18 Nov 2017 18:49:42 +0100 Disable ReplyTo if System Message.
7472f78 csoler Wed, 15 Nov 2017 23:24:43 +0100 added sha256 calculation functions, and non backward compatible SSL Id computation code to active later (0.7)
ce14219 csoler Tue, 14 Nov 2017 21:39:46 +0100 merged with upstream/master
9f8f0e9 csoler Tue, 14 Nov 2017 21:36:04 +0100 fixed column names in keyring
ba7cf49 csoler Tue, 14 Nov 2017 20:53:24 +0100 Merge pull request #1037 from RetroPooh/searchspy
556f93c csoler Tue, 14 Nov 2017 20:51:25 +0100 Merge pull request #1108 from RetroPooh/smallfixes2
2f6517a csoler Tue, 14 Nov 2017 20:50:57 +0100 Merge pull request #1112 from RetroPooh/coll_name_as_dir
fdced92 csoler Tue, 14 Nov 2017 20:41:48 +0100 Merge pull request #1111 from RetroPooh/searstr
1f207ba RetroP Tue, 14 Nov 2017 19:52:48 +0300 create collection dialog filename as dir name
919d650 RetroP Tue, 14 Nov 2017 16:09:05 +0300 in search strings change comma to space for better look
9aa6dd3 Pooh Tue, 14 Nov 2017 14:34:22 +0300 Update rsturtleitem.h
8368a76 csoler Mon, 13 Nov 2017 23:38:25 +0100 Merge pull request #1110 from csoler/v0.6-FT
5fab053 csoler Mon, 13 Nov 2017 23:37:53 +0100 added toStdString() method to search strings so as to display what is searched
7304c48 csoler Mon, 13 Nov 2017 22:32:30 +0100 Merge pull request #1109 from csoler/v0.6-Links2
5d6225a RetroP Tue, 14 Nov 2017 00:14:16 +0300 sort by time, nicer look
1669cd4 csoler Mon, 13 Nov 2017 22:08:05 +0100 use "download..." menu with RsCollectionDialog with multiple files and directories
f369ac1 RetroP Mon, 13 Nov 2017 19:05:16 +0300 fix mail fields stretching with CC BCC
45c8e9e csoler Mon, 13 Nov 2017 11:01:48 +0100 Merge pull request #1107 from csoler/v0.6-Links2
5997c10 csoler Sun, 12 Nov 2017 22:46:29 +0100 fixed bug causing RsCollection to fail on remote files. Now using RsCollectionDialog when downloading directories from friend shared files
c0951b3 csoler Sun, 12 Nov 2017 21:33:21 +0100 Merge pull request #1040 from RetroPooh/searchmultinames2
240d3a6 csoler Sat, 11 Nov 2017 16:33:30 +0100 Merge pull request #1104 from RetroPooh/linkaddrtooltips
cb77243 csoler Sat, 11 Nov 2017 16:31:33 +0100 Merge pull request #1105 from RetroPooh/smallfixes1
9b66e7e RetroP Fri, 10 Nov 2017 18:32:18 +0300 fix non-latin peer name display in bw stats
792f7ff RetroP Fri, 10 Nov 2017 18:31:41 +0300 fix status led icons for distant chat
df244fd RetroP Fri, 10 Nov 2017 16:01:11 +0300 add tooltips with address to urls
7feb630 csoler Wed, 8 Nov 2017 20:11:26 +0100 Merge pull request #1102 from csoler/v0.6-Links2
6a8bc8b csoler Wed, 8 Nov 2017 18:11:46 +0100 use of RsCollectionDialog for processing single file links. Only "extra" links still require the older processing system because RsCollections cannot have sources for each entry
-- Retroshare Dev Team <contact@retroshare.net> Thu, 24 Dec 2017 10:00:00 +0100
retroshare (0.6.3-1.20171107.c67143d4~wily) wily; urgency=low
68b35f3 Phenom Tue, 15 Aug 2017 19:45:26 +0200 Fix CppCheck in notifytxt.cc 68b35f3 Phenom Tue, 15 Aug 2017 19:45:26 +0200 Fix CppCheck in notifytxt.cc
0b8d684 Phenom Tue, 15 Aug 2017 19:11:32 +0200 Fix CppCheck in framecatcher.cpp 0b8d684 Phenom Tue, 15 Aug 2017 19:11:32 +0200 Fix CppCheck in framecatcher.cpp
deb6693 Phenom Tue, 15 Aug 2017 19:00:17 +0200 Fix CppCheck in idle.cpp deb6693 Phenom Tue, 15 Aug 2017 19:00:17 +0200 Fix CppCheck in idle.cpp

View File

@ -1403,13 +1403,33 @@ bool DistributedChatService::acceptLobbyInvite(const ChatLobbyId& lobby_id,const
return false; 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()) if(_chat_lobbys.find(lobby_id) != _chat_lobbys.end())
{ {
std::cerr << " (II) Lobby already exists. Weird." << std::endl; std::cerr << " (II) Lobby already exists. Weird." << std::endl;
return true ; return true ;
} }
#ifdef DEBUG_CHAT_LOBBIES #ifdef DEBUG_CHAT_LOBBIES
std::cerr << " Creating new Lobby entry." << std::endl; std::cerr << " Creating new Lobby entry." << std::endl;
#endif #endif
@ -1491,9 +1511,10 @@ void DistributedChatService::denyLobbyInvite(const ChatLobbyId& lobby_id)
bool DistributedChatService::joinVisibleChatLobby(const ChatLobbyId& lobby_id,const RsGxsId& gxs_id) bool DistributedChatService::joinVisibleChatLobby(const ChatLobbyId& lobby_id,const RsGxsId& gxs_id)
{ {
if(!mGixs->isOwnId(gxs_id)) RsIdentityDetails det ;
if( (!rsIdentity->getIdDetails(gxs_id,det)) || !(det.mFlags & RS_IDENTITY_FLAGS_IS_OWN_ID))
{ {
std::cerr << "(EE) Cannot lobby using gxs id " << gxs_id << std::endl; std::cerr << " (EE) Cannot subscribe with identity " << gxs_id << " because it is not ours! Something's wrong here." << std::endl;
return false ; return false ;
} }
@ -1527,6 +1548,12 @@ bool DistributedChatService::joinVisibleChatLobby(const ChatLobbyId& lobby_id,co
return true ; 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 #ifdef DEBUG_CHAT_LOBBIES
std::cerr << " Creating new lobby entry." << std::endl; std::cerr << " Creating new lobby entry." << std::endl;
#endif #endif

View File

@ -734,13 +734,39 @@ bool ftController::completeFile(const RsFileHash& hash)
fc->mState = ftFileControl::COMPLETED; 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, // 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. // 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) ) 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; fc->mCurrentPath = fc->mDestination;
else else
fc->mState = ftFileControl::ERROR_COMPLETION; fc->mState = ftFileControl::ERROR_COMPLETION;
}
else
fc->mState = ftFileControl::ERROR_COMPLETION;
}
/* for extralist additions */ /* for extralist additions */
path = fc->mDestination; path = fc->mDestination;

View File

@ -1382,7 +1382,11 @@ ops_secret_key_t *secret_key = NULL ;
// then do the signature. // then do the signature.
ops_boolean_t not_raw = !use_raw_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) if(!memres)
return false ; 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) 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 ; return false ;
unsigned char bytes[8] ; unsigned char bytes[8] ;
for(int i=0;i<8;++i) for(int i=0;i<8;++i)
{ {
bytes[7-i] = issuer & 0xff ; bytes[7-i] = info.issuer & 0xff ;
issuer >>= 8 ; info.issuer >>= 8 ;
} }
issuer_id = RsPgpId(bytes) ; issuer_id = RsPgpId(bytes) ;

View File

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

View File

@ -41,6 +41,46 @@
#include <stdint.h> #include <stdint.h>
#include <string> #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 // 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. // 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 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. // This class handles the parsing of PGP packet headers under various (old and new) formats.
@ -74,6 +114,8 @@ class PGPKeyManagement
class PGPKeyParser class PGPKeyParser
{ {
public: 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_PUBLIC_KEY = 6 ;
static const uint8_t PGP_PACKET_TAG_USER_ID = 13 ; static const uint8_t PGP_PACKET_TAG_USER_ID = 13 ;
static const uint8_t PGP_PACKET_TAG_SIGNATURE = 2 ; static const uint8_t PGP_PACKET_TAG_SIGNATURE = 2 ;

View File

@ -40,6 +40,7 @@
#include "rsitems/rsconfigitems.h" #include "rsitems/rsconfigitems.h"
#include "util/rsdir.h" #include "util/rsdir.h"
#include "util/rsstring.h" #include "util/rsstring.h"
#include "pgp/pgpkeyutil.h"
#include "retroshare/rspeers.h" // for RsPeerDetails structure #include "retroshare/rspeers.h" // for RsPeerDetails structure
#include "retroshare/rsids.h" // for RsPeerDetails structure #include "retroshare/rsids.h" // for RsPeerDetails structure
@ -61,6 +62,10 @@ 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_MALLOC_ERROR = 0x04 ;
const uint32_t RS_SSL_HANDSHAKE_DIAGNOSTIC_WRONG_SIGNATURE = 0x05 ; 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_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 * #define AUTHSSL_DEBUG 1
@ -528,6 +533,7 @@ bool AuthSSLimpl::validateOwnCertificate(X509 *x509, EVP_PKEY *pkey)
/* standard authentication */ /* standard authentication */
if (!AuthX509WithGPG(x509,diagnostic)) if (!AuthX509WithGPG(x509,diagnostic))
{ {
std::cerr << "Validate Own certificate ERROR: diagnostic = " << diagnostic << std::endl;
return false; return false;
} }
return true; return true;
@ -702,7 +708,6 @@ X509 *AuthSSLimpl::SignX509ReqWithGPG(X509_REQ *req, long /*days*/)
#define SERIAL_RAND_BITS 64 #define SERIAL_RAND_BITS 64
//const EVP_MD *digest = EVP_sha1(); //const EVP_MD *digest = EVP_sha1();
ASN1_INTEGER *serial = ASN1_INTEGER_new();
EVP_PKEY *tmppkey; EVP_PKEY *tmppkey;
X509 *x509 = X509_new(); X509 *x509 = X509_new();
if (x509 == NULL) 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; 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(); BIGNUM *btmp = BN_new();
BN_set_word(btmp,CERTIFICATE_SERIAL_NUMBER) ;
#ifdef OLD_CODE
if (!BN_pseudo_rand(btmp, SERIAL_RAND_BITS, 0, 0)) if (!BN_pseudo_rand(btmp, SERIAL_RAND_BITS, 0, 0))
{ {
std::cerr << "AuthSSLimpl::SignX509Req() rand FAIL" << std::endl; std::cerr << "AuthSSLimpl::SignX509Req() rand FAIL" << std::endl;
return NULL; return NULL;
} }
#endif
ASN1_INTEGER *serial = ASN1_INTEGER_new();
if (!BN_to_ASN1_INTEGER(btmp, serial)) if (!BN_to_ASN1_INTEGER(btmp, serial))
{ {
std::cerr << "AuthSSLimpl::SignX509Req() asn1 FAIL" << std::endl; 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_notBefore(x509), 0);
ASN1_TIME_set(X509_get_notAfter(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))) if (!X509_set_subject_name(x509, X509_REQ_get_subject_name(req)))
{ {
std::cerr << "AuthSSLimpl::SignX509Req() sub FAIL" << std::endl; 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); ASN1_BIT_STRING *signature = const_cast<ASN1_BIT_STRING*>(tmp_signature);
#endif #endif
//EVP_PKEY *pkey = NULL; //EVP_PKEY *pkey = NULL;
#ifdef V07_NON_BACKWARD_COMPATIBLE_CHANGE_002
const EVP_MD *type = EVP_sha256();
#else
const EVP_MD *type = EVP_sha1(); const EVP_MD *type = EVP_sha1();
#endif
EVP_MD_CTX *ctx = EVP_MD_CTX_create(); EVP_MD_CTX *ctx = EVP_MD_CTX_create();
int inl=0,hashoutl=0; int inl=0;
int sigoutl=0;
X509_ALGOR *a; X509_ALGOR *a;
/* FIX ALGORITHMS */ /* FIX ALGORITHMS */
@ -851,23 +860,47 @@ X509 *AuthSSLimpl::SignX509ReqWithGPG(X509_REQ *req, long /*days*/)
std::cerr << "Algorithms Fixed" << std::endl; 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 */ /* input buffer */
#if OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER) #if OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER)
inl=i2d(data,NULL); inl=i2d(data,NULL);
unsigned char *buf_in=(unsigned char *)OPENSSL_malloc((unsigned int)inl); 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 #else
unsigned char *buf_in=NULL; unsigned char *buf_in=NULL;
inl=i2d_re_X509_tbs(x509,&buf_in) ; // this does the i2d over x509->cert_info inl=i2d_re_X509_tbs(x509,&buf_in) ; // this does the i2d over x509->cert_info
#endif #endif
hashoutl=EVP_MD_size(type); #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;
/* 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); unsigned char *buf_hashout=(unsigned char *)OPENSSL_malloc((unsigned int)hashoutl);
sigoutl=2048; // hashoutl; //EVP_PKEY_size(pkey); if((buf_hashout == NULL) || (buf_sigout == NULL))
unsigned char *buf_sigout=(unsigned char *)OPENSSL_malloc((unsigned int)sigoutl);
if ((buf_in == NULL) || (buf_hashout == NULL) || (buf_sigout == NULL))
{ {
hashoutl=0; hashoutl=0;
sigoutl=0; sigoutl=0;
@ -876,16 +909,10 @@ X509 *AuthSSLimpl::SignX509ReqWithGPG(X509_REQ *req, long /*days*/)
} }
std::cerr << "Buffers Allocated" << std::endl; std::cerr << "Buffers Allocated" << std::endl;
#if OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER)
p=buf_in;
i2d(data,&p);
#endif
/* data in buf_in, ready to be hashed */ /* data in buf_in, ready to be hashed */
EVP_DigestInit_ex(ctx,type, NULL); EVP_DigestInit_ex(ctx,type, NULL);
EVP_DigestUpdate(ctx,(unsigned char *)buf_in,inl); EVP_DigestUpdate(ctx,(unsigned char *)buf_in,inl);
if (!EVP_DigestFinal(ctx,(unsigned char *)buf_hashout, if (!EVP_DigestFinal(ctx,(unsigned char *)buf_hashout, (unsigned int *)&hashoutl))
(unsigned int *)&hashoutl))
{ {
hashoutl=0; hashoutl=0;
fprintf(stderr, "AuthSSLimpl::SignX509Req: ASN1err(ASN1_F_ASN1_SIGN,ERR_R_EVP_LIB)\n"); fprintf(stderr, "AuthSSLimpl::SignX509Req: ASN1err(ASN1_F_ASN1_SIGN,ERR_R_EVP_LIB)\n");
@ -900,9 +927,12 @@ X509 *AuthSSLimpl::SignX509ReqWithGPG(X509_REQ *req, long /*days*/)
sigoutl = 0; sigoutl = 0;
goto err; goto err;
} }
#endif
std::cerr << "Buffer Sizes: in: " << inl; std::cerr << "Buffer Sizes: in: " << inl;
#ifndef V07_NON_BACKWARD_COMPATIBLE_CHANGE_003
std::cerr << " HashOut: " << hashoutl; std::cerr << " HashOut: " << hashoutl;
#endif
std::cerr << " SigOut: " << sigoutl; std::cerr << " SigOut: " << sigoutl;
std::cerr << std::endl; std::cerr << std::endl;
@ -926,6 +956,13 @@ X509 *AuthSSLimpl::SignX509ReqWithGPG(X509_REQ *req, long /*days*/)
EVP_MD_CTX_destroy(ctx) ; 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; return x509;
/* XXX CLEANUP */ /* XXX CLEANUP */
@ -933,8 +970,10 @@ X509 *AuthSSLimpl::SignX509ReqWithGPG(X509_REQ *req, long /*days*/)
/* cleanup */ /* cleanup */
if(buf_in != NULL) if(buf_in != NULL)
OPENSSL_free(buf_in) ; OPENSSL_free(buf_in) ;
#ifndef V07_NON_BACKWARD_COMPATIBLE_CHANGE_003
if(buf_hashout != NULL) if(buf_hashout != NULL)
OPENSSL_free(buf_hashout) ; OPENSSL_free(buf_hashout) ;
#endif
if(buf_sigout != NULL) if(buf_sigout != NULL)
OPENSSL_free(buf_sigout) ; OPENSSL_free(buf_sigout) ;
std::cerr << "GPGAuthMgr::SignX509Req() err: FAIL" << std::endl; 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); X509_get0_signature(&signature,&algor2,x509);
#endif #endif
uint32_t certificate_version = getX509RetroshareCertificateVersion(x509) ;
const EVP_MD *type = EVP_sha1();
EVP_MD_CTX *ctx = EVP_MD_CTX_create(); EVP_MD_CTX *ctx = EVP_MD_CTX_create();
int inl=0,hashoutl=0; int inl=0;
int sigoutl=0;
const unsigned char *signed_data = NULL ;
uint32_t signed_data_length =0;
/* input buffer */ /* input buffer */
#if OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER) #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 inl=i2d_re_X509_tbs(x509,&buf_in) ; // this does the i2d over x509->cert_info
#endif #endif
hashoutl=EVP_MD_size(type); if(buf_in == NULL)
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;
fprintf(stderr, "AuthSSLimpl::AuthX509: ASN1err(ASN1_F_ASN1_SIGN,ERR_R_MALLOC_FAILURE)\n"); fprintf(stderr, "AuthSSLimpl::AuthX509: ASN1err(ASN1_F_ASN1_SIGN,ERR_R_MALLOC_FAILURE)\n");
diagnostic = RS_SSL_HANDSHAKE_DIAGNOSTIC_MALLOC_ERROR ; diagnostic = RS_SSL_HANDSHAKE_DIAGNOSTIC_MALLOC_ERROR ;
goto err;
return false ;
} }
#ifdef AUTHSSL_DEBUG #ifdef AUTHSSL_DEBUG
@ -1038,30 +1065,23 @@ bool AuthSSLimpl::AuthX509WithGPG(X509 *x509,uint32_t& diagnostic)
p=buf_in; p=buf_in;
i2d(data,&p); i2d(data,&p);
#endif #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;
}
#ifdef AUTHSSL_DEBUG { // this scope is to avoid cross-initialization jumps to err.
std::cerr << "Digest Applied: len: " << hashoutl << std::endl;
#endif
/* copy data into signature */ const Sha1CheckSum sha1 = RsDirUtil::sha1sum(buf_in,inl) ; // olds the memory until destruction
if(sigoutl < signature->length)
if(certificate_version < RS_CERTIFICATE_VERSION_NUMBER_07_0001)
{ {
diagnostic = RS_SSL_HANDSHAKE_DIAGNOSTIC_MALLOC_ERROR ; // If the certificate belongs to 0.6 version, we hash it here, and then re-hash the hash it in the PGP signature.
goto err;
signed_data = sha1.toByteArray() ;
signed_data_length = sha1.SIZE_IN_BYTES;
}
else
{
signed_data = buf_in ;
signed_data_length = inl ;
} }
sigoutl = signature->length;
memmove(buf_sigout, signature->data, sigoutl);
/* NOW check sign via GPG Functions */ /* NOW check sign via GPG Functions */
//get the fingerprint of the key that is supposed to sign //get the fingerprint of the key that is supposed to sign
@ -1069,23 +1089,90 @@ bool AuthSSLimpl::AuthX509WithGPG(X509 *x509,uint32_t& diagnostic)
std::cerr << "AuthSSLimpl::AuthX509() verifying the gpg sig with keyprint : " << pd.fpr << std::endl; std::cerr << "AuthSSLimpl::AuthX509() verifying the gpg sig with keyprint : " << pd.fpr << std::endl;
std::cerr << "Sigoutl = " << sigoutl << std::endl ; std::cerr << "Sigoutl = " << sigoutl << std::endl ;
std::cerr << "pd.fpr = " << pd.fpr << std::endl ; std::cerr << "pd.fpr = " << pd.fpr << std::endl ;
std::cerr << "hashoutl = " << hashoutl << std::endl ;
#endif #endif
if (!AuthGPG::getAuthGPG()->VerifySignBin(buf_hashout, hashoutl, buf_sigout, (unsigned int) sigoutl, pd.fpr)) { // Take a early look at signature parameters. In particular we dont accept signatures with unsecure hash algorithms.
sigoutl = 0;
PGPSignatureInfo signature_info ;
PGPKeyManagement::parseSignature(signature->data,signature->length,signature_info) ;
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 ; diagnostic = RS_SSL_HANDSHAKE_DIAGNOSTIC_WRONG_SIGNATURE ;
goto err; 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 #ifdef AUTHSSL_DEBUG
std::cerr << "AuthSSLimpl::AuthX509() X509 authenticated" << std::endl; std::cerr << "AuthSSLimpl::AuthX509() X509 authenticated" << std::endl;
#endif #endif
EVP_MD_CTX_destroy(ctx) ; EVP_MD_CTX_destroy(ctx) ;
OPENSSL_free(buf_in) ; OPENSSL_free(buf_in) ;
OPENSSL_free(buf_hashout) ;
OPENSSL_free(buf_sigout) ;
diagnostic = RS_SSL_HANDSHAKE_DIAGNOSTIC_OK ; diagnostic = RS_SSL_HANDSHAKE_DIAGNOSTIC_OK ;
@ -1096,10 +1183,7 @@ err:
if(buf_in != NULL) if(buf_in != NULL)
OPENSSL_free(buf_in) ; OPENSSL_free(buf_in) ;
if(buf_hashout != NULL)
OPENSSL_free(buf_hashout) ;
if(buf_sigout != NULL)
OPENSSL_free(buf_sigout) ;
return false; return false;
} }

View File

@ -519,6 +519,25 @@ uint32_t p3PeerMgrIMPL::getHiddenType(const RsPeerId &ssl_id)
return (it->second).hiddenType; 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 * @brief sets hidden domain and port for a given ssl ID
* @param ssl_id peer to set domain and port for * @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.mExt.mAddrs,id,mLinkMgr) ;
cleanIpList(clean_set.mLocal.mAddrs,id,mLinkMgr) ; cleanIpList(clean_set.mLocal.mAddrs,id,mLinkMgr) ;
bool am_I_a_hidden_node = isHiddenNode(getOwnId()) ;
RsStackMutex stack(mPeerMtx); /****** STACK LOCK MUTEX *******/ RsStackMutex stack(mPeerMtx); /****** STACK LOCK MUTEX *******/
/* check if it is our own ip */ /* check if it is our own ip */
@ -1655,7 +1676,12 @@ bool p3PeerMgrIMPL::updateAddressList(const RsPeerId& id, const pqiIpAddrSet
} }
/* "it" points to peer */ /* "it" points to peer */
if(!am_I_a_hidden_node)
it->second.ipAddrs.updateAddrs(clean_set); it->second.ipAddrs.updateAddrs(clean_set);
else
it->second.ipAddrs.clear();
#ifdef PEER_DEBUG #ifdef PEER_DEBUG
std::cerr << "p3PeerMgrIMPL::setLocalAddress() Updated Address for: " << id; std::cerr << "p3PeerMgrIMPL::setLocalAddress() Updated Address for: " << id;
std::cerr << std::endl; std::cerr << std::endl;
@ -2173,6 +2199,7 @@ bool p3PeerMgrIMPL::loadList(std::list<RsItem *>& load)
#endif #endif
RsPeerId ownId = getOwnId(); RsPeerId ownId = getOwnId();
bool am_I_a_hidden_node = isHiddenNode(ownId) ;
/* load the list of peers */ /* load the list of peers */
std::list<RsItem *>::iterator it; std::list<RsItem *>::iterator it;
@ -2219,15 +2246,19 @@ bool p3PeerMgrIMPL::loadList(std::list<RsItem *>& load)
} }
else else
{
pqiIpAddrSet 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); setLocalAddress(peer_id, pitem->localAddrV4.addr);
setExtAddress(peer_id, pitem->extAddrV4.addr); setExtAddress(peer_id, pitem->extAddrV4.addr);
setDynDNS (peer_id, pitem->dyndns); setDynDNS (peer_id, pitem->dyndns);
/* convert addresses */ /* convert addresses */
pqiIpAddrSet addrs;
addrs.mLocal.extractFromTlv(pitem->localAddrList); addrs.mLocal.extractFromTlv(pitem->localAddrList);
addrs.mExt.extractFromTlv(pitem->extAddrList); addrs.mExt.extractFromTlv(pitem->extAddrList);
}
updateAddressList(peer_id, addrs); updateAddressList(peer_id, addrs);
} }

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 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 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 updateCurrentAddress(const RsPeerId& id, const pqiIpAddress &addr) = 0;
virtual bool updateLastContact(const RsPeerId& id) = 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 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 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 updateCurrentAddress(const RsPeerId& id, const pqiIpAddress &addr);
virtual bool updateLastContact(const RsPeerId& id); virtual bool updateLastContact(const RsPeerId& id);

View File

@ -68,6 +68,12 @@ class pqiIpAddrSet
void printAddrs(std::string &out) const; void printAddrs(std::string &out) const;
pqiIpAddrList mLocal; pqiIpAddrList mLocal;
pqiIpAddrList mExt; 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,6 +610,32 @@ bool getX509id(X509 *x509, RsPeerId& xid)
X509_get0_signature(&signature,&algor,x509); X509_get0_signature(&signature,&algor,x509);
#endif #endif
uint32_t version_number = getX509RetroshareCertificateVersion(x509) ;
if(version_number >= RS_CERTIFICATE_VERSION_NUMBER_06_0001)
{
// 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); int signlen = ASN1_STRING_length(signature);
if (signlen < CERTSIGNLEN) if (signlen < CERTSIGNLEN)
{ {
@ -627,14 +653,10 @@ bool getX509id(X509 *x509, RsPeerId& xid)
* more randomness * 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]) ; xid = RsPeerId(&signdata[signlen - CERTSIGNLEN]) ;
}
//for(int i = signlen - CERTSIGNLEN; i < signlen; i++)
//{
// rs_sprintf_append(xid, "%02x", (uint16_t) (((uint8_t *) (signdata))[i]));
//}
return true; return true;
} }
@ -663,6 +685,34 @@ bool CheckX509Certificate(X509 */*x509*/)
return true; 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. // Not dependent on sslroot. load, and detroys the X509 memory.
int LoadCheckX509(const char *cert_file, RsPgpId& issuerName, std::string &location, RsPeerId &userId) 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 #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( X509_REQ *GenerateX509Req(
std::string pkey_file, std::string passwd, 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 getX509CountryString(X509_NAME *name);
std::string getX509Info(X509 *cert); std::string getX509Info(X509 *cert);
uint64_t getX509SerialNumber(X509 *cert);
uint32_t getX509RetroshareCertificateVersion(X509 *cert) ;
/********** SSL ERROR STUFF ******************************************/ /********** SSL ERROR STUFF ******************************************/
int printSSLError(SSL *ssl, int retval, int err, unsigned long err2, std::string &out); int printSSLError(SSL *ssl, int retval, int err, unsigned long err2, std::string &out);

View File

@ -28,6 +28,7 @@
#include <string> #include <string>
#include <list> #include <list>
#include <stdint.h> #include <stdint.h>
#include "util/rsprint.h"
#include "retroshare/rstypes.h" #include "retroshare/rstypes.h"
/****************************************************************************************** /******************************************************************************************
@ -86,6 +87,8 @@ public:
static Expression *toExpr(const LinearizedExpression& e) ; static Expression *toExpr(const LinearizedExpression& e) ;
std::string GetStrings();
private: private:
static Expression *toExpr(const LinearizedExpression& e,int&,int&,int&) ; 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) ; 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 ~Expression() {};
virtual void linearize(LinearizedExpression& e) const = 0 ; virtual void linearize(LinearizedExpression& e) const = 0 ;
virtual std::string toStdString() const = 0 ;
}; };
class CompoundExpression : public Expression class CompoundExpression : public Expression
@ -155,6 +159,18 @@ public:
delete Rexp; 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 ; virtual void linearize(LinearizedExpression& e) const ;
private: private:
Expression *Lexp; Expression *Lexp;
@ -169,6 +185,7 @@ public:
StringExpression(enum StringOperator op, std::list<std::string> &t, bool ic): Op(op),terms(t), IgnoreCase(ic){} StringExpression(enum StringOperator op, std::list<std::string> &t, bool ic): Op(op),terms(t), IgnoreCase(ic){}
virtual void linearize(LinearizedExpression& e) const ; virtual void linearize(LinearizedExpression& e) const ;
virtual std::string toStdString(const std::string& varstr) const;
protected: protected:
bool evalStr(const std::string &str); 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) {} RelExpression(enum RelOperator op, T lv, T hv): Op(op), LowerValue(lv), HigherValue(hv) {}
virtual void linearize(LinearizedExpression& e) const ; virtual void linearize(LinearizedExpression& e) const ;
virtual std::string toStdString(const std::string& typestr) const;
protected: protected:
bool evalRel(T val); 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 Binary Predicate for Case Insensitive search
@ -245,6 +279,8 @@ public:
StringExpression(op,t,ic) {} StringExpression(op,t,ic) {}
bool eval(const ExpFileEntry& file); bool eval(const ExpFileEntry& file);
virtual std::string toStdString() const { return StringExpression::toStdString("NAME"); }
virtual void linearize(LinearizedExpression& e) const virtual void linearize(LinearizedExpression& e) const
{ {
e._tokens.push_back(LinearizedExpression::EXPR_NAME) ; e._tokens.push_back(LinearizedExpression::EXPR_NAME) ;
@ -258,6 +294,8 @@ public:
StringExpression(op,t,ic) {} StringExpression(op,t,ic) {}
bool eval(const ExpFileEntry& file); bool eval(const ExpFileEntry& file);
virtual std::string toStdString()const { return StringExpression::toStdString("PATH"); }
virtual void linearize(LinearizedExpression& e) const virtual void linearize(LinearizedExpression& e) const
{ {
e._tokens.push_back(LinearizedExpression::EXPR_PATH) ; e._tokens.push_back(LinearizedExpression::EXPR_PATH) ;
@ -271,6 +309,8 @@ public:
StringExpression(op,t,ic) {} StringExpression(op,t,ic) {}
bool eval(const ExpFileEntry& file); bool eval(const ExpFileEntry& file);
virtual std::string toStdString()const { return StringExpression::toStdString("EXTENSION"); }
virtual void linearize(LinearizedExpression& e) const virtual void linearize(LinearizedExpression& e) const
{ {
e._tokens.push_back(LinearizedExpression::EXPR_EXT) ; e._tokens.push_back(LinearizedExpression::EXPR_EXT) ;
@ -284,6 +324,8 @@ public:
StringExpression(op,t, true) {} StringExpression(op,t, true) {}
bool eval(const ExpFileEntry& file); bool eval(const ExpFileEntry& file);
virtual std::string toStdString() const { return StringExpression::toStdString("HASH"); }
virtual void linearize(LinearizedExpression& e) const virtual void linearize(LinearizedExpression& e) const
{ {
e._tokens.push_back(LinearizedExpression::EXPR_HASH) ; e._tokens.push_back(LinearizedExpression::EXPR_HASH) ;
@ -304,6 +346,8 @@ public:
RelExpression<int>(op,lv,hv) {} RelExpression<int>(op,lv,hv) {}
bool eval(const ExpFileEntry& file); bool eval(const ExpFileEntry& file);
virtual std::string toStdString() const { return RelExpression<int>::toStdString("DATE"); }
virtual void linearize(LinearizedExpression& e) const virtual void linearize(LinearizedExpression& e) const
{ {
e._tokens.push_back(LinearizedExpression::EXPR_DATE) ; e._tokens.push_back(LinearizedExpression::EXPR_DATE) ;
@ -319,6 +363,8 @@ public:
RelExpression<int>(op,lv,hv) {} RelExpression<int>(op,lv,hv) {}
bool eval(const ExpFileEntry& file); bool eval(const ExpFileEntry& file);
virtual std::string toStdString() const { return RelExpression<int>::toStdString("SIZE"); }
virtual void linearize(LinearizedExpression& e) const virtual void linearize(LinearizedExpression& e) const
{ {
e._tokens.push_back(LinearizedExpression::EXPR_SIZE) ; e._tokens.push_back(LinearizedExpression::EXPR_SIZE) ;
@ -334,6 +380,8 @@ public:
RelExpression<int>(op,lv,hv) {} RelExpression<int>(op,lv,hv) {}
bool eval(const ExpFileEntry& file); bool eval(const ExpFileEntry& file);
virtual std::string toStdString() const { return RelExpression<int>::toStdString("SIZE"); }
virtual void linearize(LinearizedExpression& e) const virtual void linearize(LinearizedExpression& e) const
{ {
e._tokens.push_back(LinearizedExpression::EXPR_SIZE_MB) ; e._tokens.push_back(LinearizedExpression::EXPR_SIZE_MB) ;
@ -348,6 +396,8 @@ public:
PopExpression(const LinearizedExpression& e) ; PopExpression(const LinearizedExpression& e) ;
bool eval(const ExpFileEntry& file); bool eval(const ExpFileEntry& file);
virtual std::string toStdString() const { return RelExpression<int>::toStdString("POPULARITY"); }
virtual void linearize(LinearizedExpression& e) const virtual void linearize(LinearizedExpression& e) const
{ {
e._tokens.push_back(LinearizedExpression::EXPR_POP) ; 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_ID_SIZE = 8 ;
static const int PGP_KEY_FINGERPRINT_SIZE = 20 ; static const int PGP_KEY_FINGERPRINT_SIZE = 20 ;
static const int SHA1_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. // 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_TUNNEL_ID_TYPE = 0x0010 ;
static const uint32_t RS_GENERIC_ID_GXS_DISTANT_CHAT_ID_TYPE = 0x0011 ; 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_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< 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< 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< 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< 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 ; 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 &hidden_node_address) = 0;
virtual bool setHiddenNode(const RsPeerId &id, const std::string &address, uint16_t port) = 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 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; 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 RsPeerId source_peer_id ; // Peer that relayed the request
uint32_t age ; // Age in seconds uint32_t age ; // Age in seconds
uint32_t depth ; // Depth of the request. Might be altered. uint32_t depth ; // Depth of the request. Might be altered.
std::string keywords;
}; };
class TurtleTrafficStatisticsInfo 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) bool p3Peers::setHiddenNode(const RsPeerId &id, const std::string &address, uint16_t port)
{ {
#ifdef P3PEERS_DEBUG #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 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 &hidden_node_address);
virtual bool setHiddenNode(const RsPeerId &id, const std::string &address, uint16_t port); 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 setLocalAddress(const RsPeerId &id, const std::string &addr, uint16_t port);
virtual bool setExtAddress(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 * #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(); pkt->clear();
@ -62,6 +62,8 @@ bool populateContactInfo(const peerState &detail, RsDiscContactItem *pkt)
{ {
pkt->isHidden = false; pkt->isHidden = false;
if(include_ip_information)
{
pkt->localAddrV4.addr = detail.localaddr; pkt->localAddrV4.addr = detail.localaddr;
pkt->extAddrV4.addr = detail.serveraddr; pkt->extAddrV4.addr = detail.serveraddr;
sockaddr_storage_clear(pkt->localAddrV6.addr); sockaddr_storage_clear(pkt->localAddrV6.addr);
@ -71,6 +73,14 @@ bool populateContactInfo(const peerState &detail, RsDiscContactItem *pkt)
detail.ipAddrs.mLocal.loadTlv(pkt->localAddrList); detail.ipAddrs.mLocal.loadTlv(pkt->localAddrList);
detail.ipAddrs.mExt.loadTlv(pkt->extAddrList); 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; return true;
} }
@ -334,9 +344,8 @@ void p3discovery2::sendOwnContactInfo(const SSLID &sslid)
if (mPeerMgr->getOwnNetStatus(detail)) if (mPeerMgr->getOwnNetStatus(detail))
{ {
RsDiscContactItem *pkt = new RsDiscContactItem(); 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->version = RsUtil::retroshareVersion();
pkt->PeerId(sslid); pkt->PeerId(sslid);
#ifdef P3DISC_DEBUG #ifdef P3DISC_DEBUG
@ -372,6 +381,7 @@ void p3discovery2::recvOwnContactInfo(const SSLID &fromId, const RsDiscContactIt
mPeerMgr->setVisState(fromId, item->vs_disc, item->vs_dht); mPeerMgr->setVisState(fromId, item->vs_disc, item->vs_dht);
setPeerVersion(fromId, item->version); setPeerVersion(fromId, item->version);
updatePeerAddresses(item); updatePeerAddresses(item);
// This information will be sent out to online peers, at the receipt of their PGPList. // 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) void p3discovery2::updatePeerAddresses(const RsDiscContactItem *item)
{ {
if (item->isHidden) if (item->isHidden)
{
mPeerMgr->setHiddenDomainPort(item->sslId, item->hiddenAddr, item->hiddenPort); mPeerMgr->setHiddenDomainPort(item->sslId, item->hiddenAddr, item->hiddenPort);
}
else else
{ {
mPeerMgr->setDynDNS(item->sslId, item->dyndns); mPeerMgr->setDynDNS(item->sslId, item->dyndns);
updatePeerAddressList(item); updatePeerAddressList(item);
} }
} }
@ -440,7 +447,7 @@ void p3discovery2::updatePeerAddressList(const RsDiscContactItem *item)
if (item->isHidden) 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; pqiIpAddrSet addrsFromPeer;
addrsFromPeer.mLocal.extractFromTlv(item->localAddrList); 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)) if (mPeerMgr->getFriendNetStatus(sit->first, detail))
{ {
RsDiscContactItem *pkt = new RsDiscContactItem(); 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); pkt->PeerId(toId);
// send to each peer its own connection address. // send to each peer its own connection address.

View File

@ -907,6 +907,7 @@ void p3turtle::handleSearchRequest(RsTurtleSearchRequestItem *item)
req.origin = item->PeerId() ; req.origin = item->PeerId() ;
req.time_stamp = time(NULL) ; req.time_stamp = time(NULL) ;
req.depth = item->depth ; 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. // 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) if(exp == NULL)
return ; return ;
#ifdef P3TURTLE_DEBUG
std::cerr << "Local search on exp: " << exp->toStdString() << std::endl;
#endif
// now, search! // now, search!
rsFiles->SearchBoolExp(exp,initialResults,RS_FILE_HINTS_LOCAL | RS_FILE_HINTS_SEARCHABLE,PeerId()); 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.source_peer_id = it->second.origin ;
info.age = now - it->second.time_stamp ; info.age = now - it->second.time_stamp ;
info.depth = it->second.depth ; info.depth = it->second.depth ;
info.keywords = it->second.keywords ;
search_reqs_info.push_back(info) ; 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. 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. 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::set<uint32_t> responses; // responses to this request. Useful to avoid spamming tunnel responses.
std::string keywords;
}; };
class TurtleTunnel class TurtleTunnel

View File

@ -72,6 +72,8 @@ class RsTurtleSearchRequestItem: public RsTurtleItem
virtual void performLocalSearch(std::list<TurtleFileInfo>&) const = 0 ; // abstracts the search method 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. uint32_t request_id ; // randomly generated request id.
uint16_t depth ; // Used for limiting search depth. uint16_t depth ; // Used for limiting search depth.
}; };
@ -83,6 +85,8 @@ class RsTurtleStringSearchRequestItem: public RsTurtleSearchRequestItem
std::string match_string ; // string to match std::string match_string ; // string to match
std::string GetKeywords() { return match_string; }
virtual RsTurtleSearchRequestItem *clone() const { return new RsTurtleStringSearchRequestItem(*this) ; } virtual RsTurtleSearchRequestItem *clone() const { return new RsTurtleStringSearchRequestItem(*this) ; }
virtual void performLocalSearch(std::list<TurtleFileInfo>&) const ; virtual void performLocalSearch(std::list<TurtleFileInfo>&) const ;
@ -99,6 +103,14 @@ class RsTurtleRegExpSearchRequestItem: public RsTurtleSearchRequestItem
RsRegularExpression::LinearizedExpression expr ; // Reg Exp in linearised mode 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 RsTurtleSearchRequestItem *clone() const { return new RsTurtleRegExpSearchRequestItem(*this) ; }
virtual void performLocalSearch(std::list<TurtleFileInfo>&) const ; 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] ; 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) void RsDirUtil::removeTopDir(const std::string& dir, std::string& path)
{ {
path.clear(); path.clear();
@ -245,6 +262,19 @@ bool RsDirUtil::fileExists(const std::string& filename)
bool RsDirUtil::moveFile(const std::string& source,const std::string& dest) 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 // 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 << "check_create_directory() Fatal Error et oui--";
std::cerr <<std::endl<< "\tcannot create:" <<dir<<std::endl; std::cerr <<std::endl<< "\tcannot create:" <<dir<<std::endl;
#endif #endif
return 0; return false;
} }
#ifdef RSDIR_DEBUG #ifdef RSDIR_DEBUG
@ -466,7 +496,7 @@ bool RsDirUtil::checkCreateDirectory(const std::string& dir)
std::cerr <<std::endl<< "\tcreated:" <<dir<<std::endl; std::cerr <<std::endl<< "\tcreated:" <<dir<<std::endl;
#endif #endif
return 1; return true;
} }
#ifdef RSDIR_DEBUG #ifdef RSDIR_DEBUG
@ -480,7 +510,7 @@ bool RsDirUtil::checkCreateDirectory(const std::string& dir)
closedir(direc) ; closedir(direc) ;
#endif #endif
return 1; return true;
} }
@ -610,6 +640,27 @@ Sha1CheckSum RsDirUtil::sha1sum(const unsigned char *data, uint32_t size)
return Sha1CheckSum(sha_buf) ; 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) 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); 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); 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 copyFile(const std::string& source,const std::string& dest);
bool moveFile(const std::string& source,const std::string& dest); bool moveFile(const std::string& source,const std::string& dest);
bool removeFile(const std::string& file); bool removeFile(const std::string& file);
@ -102,6 +107,7 @@ bool hashFile(const std::string& filepath, std::string &name, RsFileHash &ha
bool getFileHash(const std::string& filepath,RsFileHash &hash, uint64_t &size, RsThread *thread = NULL); 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 saveStringToFile(const std::string& file, const std::string& str);
bool loadStringFromFile(const std::string& file, 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 ){ bool StringExpression :: evalStr ( const std::string &str ){
std::list<std::string>::iterator iter; std::list<std::string>::iterator iter;
switch (Op) { switch (Op) {
@ -199,6 +225,17 @@ void LinearizedExpression::readStringExpr(const LinearizedExpression& e,int& n_i
strings.push_back(e._strings[n_strings++]) ; 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) 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++]) ; LinearizedExpression::token tok = static_cast<LinearizedExpression::token>(e._tokens[n_tok++]) ;

View File

@ -348,7 +348,10 @@ typedef enum
// SHA1 Hash Size \todo is this the same as OPS_CHECKHASH_SIZE?? // SHA1 Hash Size \todo is this the same as OPS_CHECKHASH_SIZE??
#define OPS_SHA1_HASH_SIZE SHA_DIGEST_LENGTH #define OPS_SHA1_HASH_SIZE SHA_DIGEST_LENGTH
#define OPS_SHA224_HASH_SIZE SHA224_DIGEST_LENGTH
#define OPS_SHA256_HASH_SIZE SHA256_DIGEST_LENGTH #define OPS_SHA256_HASH_SIZE SHA256_DIGEST_LENGTH
#define OPS_SHA384_HASH_SIZE SHA384_DIGEST_LENGTH
#define OPS_SHA512_HASH_SIZE SHA512_DIGEST_LENGTH
// Max hash size // Max hash size
#define OPS_MAX_HASH_SIZE 64 #define OPS_MAX_HASH_SIZE 64

View File

@ -216,8 +216,49 @@ static ops_boolean_t rsa_sign(ops_hash_t *hash, const ops_rsa_public_key_t *rsa,
unsigned t; unsigned t;
BIGNUM *bn; BIGNUM *bn;
int plen ;
unsigned int hash_length ;
unsigned char *prefix ;
switch(hash->algorithm)
{
case OPS_HASH_SHA1: hashsize=OPS_SHA1_HASH_SIZE+sizeof prefix_sha1;
hash_length=OPS_SHA1_HASH_SIZE ;
prefix = prefix_sha1;
plen = sizeof prefix_sha1 ;
break ;
case OPS_HASH_SHA224: hashsize=OPS_SHA224_HASH_SIZE+sizeof prefix_sha224;
hash_length=OPS_SHA224_HASH_SIZE ;
prefix = prefix_sha224;
plen = sizeof prefix_sha224 ;
break ;
case OPS_HASH_SHA256: hashsize=OPS_SHA256_HASH_SIZE+sizeof prefix_sha256;
hash_length=OPS_SHA256_HASH_SIZE ;
prefix = prefix_sha256;
plen = sizeof prefix_sha256 ;
break ;
case OPS_HASH_SHA384: hashsize=OPS_SHA384_HASH_SIZE+sizeof prefix_sha384;
hash_length=OPS_SHA384_HASH_SIZE ;
prefix = prefix_sha384;
plen = sizeof prefix_sha384 ;
break ;
case OPS_HASH_SHA512: hashsize=OPS_SHA512_HASH_SIZE+sizeof prefix_sha512;
hash_length=OPS_SHA512_HASH_SIZE ;
prefix = prefix_sha512;
plen = sizeof prefix_sha512 ;
break ;
case OPS_HASH_MD5: fprintf(stderr,"(insecure) MD5+RSA signatures not supported in RSA sign") ;
return ops_false ;
default: fprintf(stderr,"Hash algorithm %d not supported in RSA sign",hash->algorithm) ;
return ops_false ;
}
// XXX: we assume hash is sha-1 for now // XXX: we assume hash is sha-1 for now
hashsize=20+sizeof prefix_sha1;
keysize=BN_num_bytes(rsa->n); keysize=BN_num_bytes(rsa->n);
@ -240,12 +281,12 @@ static ops_boolean_t rsa_sign(ops_hash_t *hash, const ops_rsa_public_key_t *rsa,
hashbuf[n]=0xff; hashbuf[n]=0xff;
hashbuf[n++]=0; hashbuf[n++]=0;
memcpy(&hashbuf[n], prefix_sha1, sizeof prefix_sha1); memcpy(&hashbuf[n], prefix, plen);
n+=sizeof prefix_sha1; n+=plen;
t=hash->finish(hash, &hashbuf[n]); t=hash->finish(hash, &hashbuf[n]);
if(t != 20) if(t != hash_length)
{ {
fprintf(stderr,"Wrong hash size. Should be 20! can't sign.") ; fprintf(stderr,"Wrong hash size. Should be 20! can't sign.") ;
return ops_false ; return ops_false ;
@ -1377,6 +1418,7 @@ void example(const ops_secret_key_t *skey)
*/ */
ops_memory_t* ops_sign_buf(const void* input, const size_t input_len, ops_memory_t* ops_sign_buf(const void* input, const size_t input_len,
const ops_sig_type_t sig_type, const ops_sig_type_t sig_type,
const ops_hash_algorithm_t hash_algorithm,
const ops_secret_key_t *skey, const ops_secret_key_t *skey,
const ops_boolean_t use_armour, const ops_boolean_t use_armour,
ops_boolean_t include_data, ops_boolean_t include_data,
@ -1392,7 +1434,7 @@ ops_memory_t* ops_sign_buf(const void* input, const size_t input_len,
ops_create_info_t *cinfo=NULL; ops_create_info_t *cinfo=NULL;
ops_memory_t *mem=ops_memory_new(); ops_memory_t *mem=ops_memory_new();
ops_hash_algorithm_t hash_alg=OPS_HASH_SHA1; ops_hash_algorithm_t hash_alg=hash_algorithm ;
ops_literal_data_type_t ld_type; ops_literal_data_type_t ld_type;
ops_hash_t* hash=NULL; ops_hash_t* hash=NULL;

View File

@ -90,7 +90,7 @@ void ops_signature_add_primary_user_id(ops_create_signature_t *sig,
ops_boolean_t ops_sign_file_as_cleartext(const char* input_filename, const char* output_filename, const ops_secret_key_t *skey, const ops_boolean_t overwrite); ops_boolean_t ops_sign_file_as_cleartext(const char* input_filename, const char* output_filename, const ops_secret_key_t *skey, const ops_boolean_t overwrite);
ops_boolean_t ops_sign_buf_as_cleartext(const char* input, const size_t len, ops_memory_t** output, const ops_secret_key_t *skey); ops_boolean_t ops_sign_buf_as_cleartext(const char* input, const size_t len, ops_memory_t** output, const ops_secret_key_t *skey);
ops_boolean_t ops_sign_file(const char* input_filename, const char* output_filename, const ops_secret_key_t *skey, const ops_boolean_t use_armour, const ops_boolean_t overwrite); ops_boolean_t ops_sign_file(const char* input_filename, const char* output_filename, const ops_secret_key_t *skey, const ops_boolean_t use_armour, const ops_boolean_t overwrite);
ops_memory_t * ops_sign_buf(const void* input, const size_t input_len, const ops_sig_type_t sig_type, const ops_secret_key_t *skey, const ops_boolean_t use_armour,ops_boolean_t include_data,ops_boolean_t include_creation_time,ops_boolean_t include_key_id); ops_memory_t * ops_sign_buf(const void* input, const size_t input_len, const ops_sig_type_t sig_type, const ops_hash_algorithm_t hash_algorithm, const ops_secret_key_t *skey, const ops_boolean_t use_armour, ops_boolean_t include_data, ops_boolean_t include_creation_time, ops_boolean_t include_key_id);
ops_boolean_t ops_writer_push_signed(ops_create_info_t *cinfo, const ops_sig_type_t sig_type, const ops_secret_key_t *skey); ops_boolean_t ops_writer_push_signed(ops_create_info_t *cinfo, const ops_sig_type_t sig_type, const ops_secret_key_t *skey);
#endif #endif

View File

@ -116,10 +116,10 @@ macx {
} }
} }
} }
DEPENDPATH += . $$INC_DIRs DEPENDPATH += . $$INC_DIR
INCLUDEPATH += . $$INC_DIR INCLUDEPATH += . $$INC_DIR
LIBS = -lcurl -lxml2 -lxslt -lcrypto LIBS += -lcurl -lxml2 -lxslt -lcrypto
} }
openbsd-* { openbsd-* {

View File

@ -1078,17 +1078,38 @@ void ChatLobbyWidget::readChatLobbyInvites()
RsGxsId default_id ; RsGxsId default_id ;
rsMsgs->getDefaultIdentityForChatLobby(default_id) ; rsMsgs->getDefaultIdentityForChatLobby(default_id) ;
std::list<ChatLobbyId> subscribed_lobbies ;
rsMsgs->getChatLobbyList(subscribed_lobbies) ;
for(std::list<ChatLobbyInvite>::const_iterator it(invites.begin());it!=invites.end();++it) for(std::list<ChatLobbyInvite>::const_iterator it(invites.begin());it!=invites.end();++it)
{ {
// first check if the lobby is already subscribed. If so, just ignore the request.
bool found = false ;
for(auto it2(subscribed_lobbies.begin());it2!=subscribed_lobbies.end() && !found;++it2)
found = found || (*it2 == (*it).lobby_id) ;
if(found)
continue ;
QMessageBox mb(QObject::tr("Join chat room"), QMessageBox mb(QObject::tr("Join chat room"),
tr("%1 invites you to chat room named %2").arg(QString::fromUtf8(rsPeers->getPeerName((*it).peer_id).c_str())).arg(RsHtml::plainText(it->lobby_name)), tr("%1 invites you to chat room named %2").arg(QString::fromUtf8(rsPeers->getPeerName((*it).peer_id).c_str())).arg(RsHtml::plainText(it->lobby_name)),
QMessageBox::Question, QMessageBox::Yes,QMessageBox::No, 0); QMessageBox::Question, QMessageBox::Yes,QMessageBox::No, 0);
QLabel *label = new QLabel(tr("Choose an identity for this chat room:")); QLabel *label ;
GxsIdChooser *idchooser = new GxsIdChooser ; GxsIdChooser *idchooser = new GxsIdChooser ;
idchooser->loadIds(IDCHOOSER_ID_REQUIRED,default_id) ;
if( (*it).lobby_flags & RS_CHAT_LOBBY_FLAGS_PGP_SIGNED )
{
idchooser->loadIds(IDCHOOSER_ID_REQUIRED | IDCHOOSER_NON_ANONYMOUS,default_id) ;
label = new QLabel(tr("Choose a non anonymous identity for this chat room:"));
}
else
{
idchooser->loadIds(IDCHOOSER_ID_REQUIRED,default_id) ;
label = new QLabel(tr("Choose an identity for this chat room:"));
}
QGridLayout* layout = qobject_cast<QGridLayout*>(mb.layout()); QGridLayout* layout = qobject_cast<QGridLayout*>(mb.layout());
if (layout) { if (layout) {

View File

@ -445,10 +445,10 @@ void SearchDialog::collCreate()
details.type = DIR_TYPE_FILE; details.type = DIR_TYPE_FILE;
dirVec.push_back(details); dirVec.push_back(details);
}//if (!item->text(SR_HASH_COL).isEmpty()) }
}//for (int i = 0; i < numdls; ++i) }
RsCollection(dirVec).openNewColl(this); RsCollection(dirVec,RS_FILE_HINTS_LOCAL).openNewColl(this);
} }
void SearchDialog::collModif() void SearchDialog::collModif()
@ -795,8 +795,7 @@ void SearchDialog::advancedSearch(RsRegularExpression::Expression* expression)
TurtleRequestId req_id = rsTurtle->turtleSearch(e) ; TurtleRequestId req_id = rsTurtle->turtleSearch(e) ;
// This will act before turtle results come to the interface, thanks to the signals scheduling policy. // This will act before turtle results come to the interface, thanks to the signals scheduling policy.
// The text "bool exp" should be replaced by an appropriate text describing the actual search. initSearchResult(QString::fromStdString(e.GetStrings()),req_id, ui.FileTypeComboBox->currentIndex(), true) ;
initSearchResult("bool exp",req_id, ui.FileTypeComboBox->currentIndex(), true) ;
rsFiles -> SearchBoolExp(expression, results, RS_FILE_HINTS_REMOTE);// | DIR_FLAGS_NETWORK_WIDE | DIR_FLAGS_BROWSABLE); rsFiles -> SearchBoolExp(expression, results, RS_FILE_HINTS_REMOTE);// | DIR_FLAGS_NETWORK_WIDE | DIR_FLAGS_BROWSABLE);

View File

@ -509,9 +509,20 @@ void RemoteSharedFilesDialog::spawnCustomPopupMenu( QPoint point )
collectionMenu.addAction(collCreateAct); collectionMenu.addAction(collCreateAct);
collectionMenu.addAction(collOpenAct); collectionMenu.addAction(collOpenAct);
QModelIndexList list = ui.dirTreeView->selectionModel()->selectedRows() ;
if(type == DIR_TYPE_DIR || list.size() > 1)
{
QAction *downloadActI = new QAction(QIcon(IMAGE_DOWNLOAD), tr( "Download..." ), &contextMnu ) ;
connect( downloadActI , SIGNAL( triggered() ), this, SLOT( downloadRemoteSelectedInteractive() ) ) ;
contextMnu.addAction( downloadActI) ;
}
else
{
QAction *downloadAct = new QAction(QIcon(IMAGE_DOWNLOAD), tr( "Download" ), &contextMnu ) ; QAction *downloadAct = new QAction(QIcon(IMAGE_DOWNLOAD), tr( "Download" ), &contextMnu ) ;
connect( downloadAct , SIGNAL( triggered() ), this, SLOT( downloadRemoteSelected() ) ) ; connect( downloadAct , SIGNAL( triggered() ), this, SLOT( downloadRemoteSelected() ) ) ;
contextMnu.addAction( downloadAct) ; contextMnu.addAction( downloadAct) ;
}
contextMnu.addSeparator() ;//------------------------------------ contextMnu.addSeparator() ;//------------------------------------
contextMnu.addAction( copylinkAct) ; contextMnu.addAction( copylinkAct) ;
@ -545,7 +556,16 @@ void RemoteSharedFilesDialog::expanded(const QModelIndex& indx)
model->updateRef(proxyModel->mapToSource(indx)) ; model->updateRef(proxyModel->mapToSource(indx)) ;
} }
void RemoteSharedFilesDialog::downloadRemoteSelectedInteractive()
{
/* call back to the model (which does all the interfacing? */
std::cerr << "Downloading Files" ;
std::cerr << std::endl ;
QModelIndexList lst = getSelected() ;
model -> downloadSelected(lst,true) ;
}
void RemoteSharedFilesDialog::downloadRemoteSelected() void RemoteSharedFilesDialog::downloadRemoteSelected()
{ {
/* call back to the model (which does all the interfacing? */ /* call back to the model (which does all the interfacing? */
@ -554,7 +574,7 @@ void RemoteSharedFilesDialog::downloadRemoteSelected()
std::cerr << std::endl ; std::cerr << std::endl ;
QModelIndexList lst = getSelected() ; QModelIndexList lst = getSelected() ;
model -> downloadSelected(lst) ; model -> downloadSelected(lst,false) ;
} }
void SharedFilesDialog::copyLinks(const QModelIndexList& lst, bool remote,QList<RetroShareLink>& urls,bool& has_unhashed_files) void SharedFilesDialog::copyLinks(const QModelIndexList& lst, bool remote,QList<RetroShareLink>& urls,bool& has_unhashed_files)

View File

@ -187,6 +187,7 @@ class RemoteSharedFilesDialog : public SharedFilesDialog
private slots: private slots:
void downloadRemoteSelected(); void downloadRemoteSelected();
void downloadRemoteSelectedInteractive();
void expanded(const QModelIndex& indx); void expanded(const QModelIndex& indx);
}; };

View File

@ -2133,7 +2133,8 @@ void TransfersDialog::collCreate()
std::set<RsFileHash>::iterator it ; std::set<RsFileHash>::iterator it ;
getDLSelectedItems(&items, NULL); getDLSelectedItems(&items, NULL);
for (it = items.begin(); it != items.end(); ++it) { for (it = items.begin(); it != items.end(); ++it)
{
FileInfo info; FileInfo info;
if (!rsFiles->FileDetails(*it, RS_FILE_HINTS_DOWNLOAD, info)) continue; if (!rsFiles->FileDetails(*it, RS_FILE_HINTS_DOWNLOAD, info)) continue;
@ -2144,9 +2145,9 @@ void TransfersDialog::collCreate()
details.type = DIR_TYPE_FILE; details.type = DIR_TYPE_FILE;
dirVec.push_back(details); dirVec.push_back(details);
}//for (it = items.begin(); }
RsCollection(dirVec).openNewColl(this); RsCollection(dirVec,RS_FILE_HINTS_LOCAL).openNewColl(this);
} }
void TransfersDialog::collModif() void TransfersDialog::collModif()

View File

@ -23,6 +23,7 @@
#include <unistd.h> #include <unistd.h>
#include <QCheckBox>
#include <QMessageBox> #include <QMessageBox>
#include <QMenu> #include <QMenu>
#include <QWidgetAction> #include <QWidgetAction>
@ -32,21 +33,23 @@
#include "IdDialog.h" #include "IdDialog.h"
#include "ui_IdDialog.h" #include "ui_IdDialog.h"
#include "IdEditDialog.h" #include "IdEditDialog.h"
#include "retroshare-gui/RsAutoUpdatePage.h" #include "gui/RetroShareLink.h"
#include "gui/chat/ChatDialog.h"
#include "gui/Circles/CreateCircleDialog.h"
#include "gui/common/UIStateHelper.h"
#include "gui/gxs/GxsIdDetails.h" #include "gui/gxs/GxsIdDetails.h"
#include "gui/gxs/RsGxsUpdateBroadcastBase.h" #include "gui/gxs/RsGxsUpdateBroadcastBase.h"
#include "gui/common/UIStateHelper.h"
#include "gui/chat/ChatDialog.h"
#include "gui/settings/rsharesettings.h"
#include "gui/msgs/MessageComposer.h" #include "gui/msgs/MessageComposer.h"
#include "gui/Circles/CreateCircleDialog.h" #include "gui/settings/rsharesettings.h"
#include "gui/RetroShareLink.h" #include "retroshare-gui/RsAutoUpdatePage.h"
#include "util/misc.h"
#include "util/QtVersion.h" #include "util/QtVersion.h"
#include <retroshare/rspeers.h>
#include "retroshare/rsgxsflags.h" #include "retroshare/rsgxsflags.h"
#include "retroshare/rsmsgs.h" #include "retroshare/rsmsgs.h"
#include "retroshare/rspeers.h"
#include "retroshare/rsservicecontrol.h" #include "retroshare/rsservicecontrol.h"
#include <iostream> #include <iostream>
#include <algorithm> #include <algorithm>
@ -175,32 +178,40 @@ IdDialog::IdDialog(QWidget *parent) :
mStateHelper->addWidget(IDDIALOG_IDDETAILS, ui->lineEdit_Nickname); mStateHelper->addWidget(IDDIALOG_IDDETAILS, ui->lineEdit_Nickname);
mStateHelper->addWidget(IDDIALOG_IDDETAILS, ui->lineEdit_KeyId); mStateHelper->addWidget(IDDIALOG_IDDETAILS, ui->lineEdit_KeyId);
// mStateHelper->addWidget(IDDIALOG_IDDETAILS, ui->lineEdit_GpgHash); mStateHelper->addWidget(IDDIALOG_IDDETAILS, ui->lineEdit_Type);
mStateHelper->addWidget(IDDIALOG_IDDETAILS, ui->lineEdit_GpgId); mStateHelper->addWidget(IDDIALOG_IDDETAILS, ui->lineEdit_GpgId);
mStateHelper->addWidget(IDDIALOG_IDDETAILS, ui->lineEdit_GpgName); mStateHelper->addWidget(IDDIALOG_IDDETAILS, ui->lineEdit_GpgName);
mStateHelper->addWidget(IDDIALOG_IDDETAILS, ui->lineEdit_Type);
mStateHelper->addWidget(IDDIALOG_IDDETAILS, ui->lineEdit_LastUsed); mStateHelper->addWidget(IDDIALOG_IDDETAILS, ui->lineEdit_LastUsed);
mStateHelper->addWidget(IDDIALOG_IDDETAILS, ui->ownOpinion_CB); mStateHelper->addWidget(IDDIALOG_IDDETAILS, ui->ownOpinion_CB);
mStateHelper->addWidget(IDDIALOG_IDDETAILS, ui->overallOpinion_TF); mStateHelper->addWidget(IDDIALOG_IDDETAILS, ui->autoBanIdentities_CB);
mStateHelper->addWidget(IDDIALOG_IDDETAILS, ui->neighborNodesOpinion_TF); mStateHelper->addWidget(IDDIALOG_IDDETAILS, ui->neighborNodesOpinion_TF);
mStateHelper->addWidget(IDDIALOG_IDDETAILS, ui->overallOpinion_TF);
mStateHelper->addWidget(IDDIALOG_IDDETAILS, ui->usageStatistics_TB);
mStateHelper->addWidget(IDDIALOG_IDDETAILS, ui->inviteButton);
mStateHelper->addWidget(IDDIALOG_IDDETAILS, ui->label_positive);
mStateHelper->addWidget(IDDIALOG_IDDETAILS, ui->label_negative);
mStateHelper->addLoadPlaceholder(IDDIALOG_IDDETAILS, ui->lineEdit_Nickname); mStateHelper->addLoadPlaceholder(IDDIALOG_IDDETAILS, ui->lineEdit_Nickname);
mStateHelper->addLoadPlaceholder(IDDIALOG_IDDETAILS, ui->lineEdit_GpgName);
mStateHelper->addLoadPlaceholder(IDDIALOG_IDDETAILS, ui->lineEdit_KeyId); mStateHelper->addLoadPlaceholder(IDDIALOG_IDDETAILS, ui->lineEdit_KeyId);
// mStateHelper->addLoadPlaceholder(IDDIALOG_IDDETAILS, ui->lineEdit_GpgHash);
mStateHelper->addLoadPlaceholder(IDDIALOG_IDDETAILS, ui->lineEdit_GpgId);
mStateHelper->addLoadPlaceholder(IDDIALOG_IDDETAILS, ui->lineEdit_Type); mStateHelper->addLoadPlaceholder(IDDIALOG_IDDETAILS, ui->lineEdit_Type);
mStateHelper->addLoadPlaceholder(IDDIALOG_IDDETAILS, ui->lineEdit_GpgId);
mStateHelper->addLoadPlaceholder(IDDIALOG_IDDETAILS, ui->lineEdit_GpgName); mStateHelper->addLoadPlaceholder(IDDIALOG_IDDETAILS, ui->lineEdit_GpgName);
mStateHelper->addLoadPlaceholder(IDDIALOG_IDDETAILS, ui->lineEdit_LastUsed); mStateHelper->addLoadPlaceholder(IDDIALOG_IDDETAILS, ui->lineEdit_LastUsed);
//mStateHelper->addLoadPlaceholder(IDDIALOG_IDDETAILS, ui->line_RatingOverall); mStateHelper->addLoadPlaceholder(IDDIALOG_IDDETAILS, ui->neighborNodesOpinion_TF);
mStateHelper->addLoadPlaceholder(IDDIALOG_IDDETAILS, ui->overallOpinion_TF);
mStateHelper->addLoadPlaceholder(IDDIALOG_IDDETAILS, ui->usageStatistics_TB);
mStateHelper->addClear(IDDIALOG_IDDETAILS, ui->lineEdit_Nickname); mStateHelper->addClear(IDDIALOG_IDDETAILS, ui->lineEdit_Nickname);
mStateHelper->addClear(IDDIALOG_IDDETAILS, ui->lineEdit_KeyId); mStateHelper->addClear(IDDIALOG_IDDETAILS, ui->lineEdit_KeyId);
// mStateHelper->addClear(IDDIALOG_IDDETAILS, ui->lineEdit_GpgHash);
mStateHelper->addClear(IDDIALOG_IDDETAILS, ui->lineEdit_GpgId);
mStateHelper->addClear(IDDIALOG_IDDETAILS, ui->lineEdit_Type); mStateHelper->addClear(IDDIALOG_IDDETAILS, ui->lineEdit_Type);
mStateHelper->addClear(IDDIALOG_IDDETAILS, ui->lineEdit_GpgId);
mStateHelper->addClear(IDDIALOG_IDDETAILS, ui->lineEdit_GpgName); mStateHelper->addClear(IDDIALOG_IDDETAILS, ui->lineEdit_GpgName);
mStateHelper->addClear(IDDIALOG_IDDETAILS, ui->lineEdit_LastUsed); mStateHelper->addClear(IDDIALOG_IDDETAILS, ui->lineEdit_LastUsed);
mStateHelper->addClear(IDDIALOG_IDDETAILS, ui->neighborNodesOpinion_TF);
mStateHelper->addClear(IDDIALOG_IDDETAILS, ui->overallOpinion_TF);
mStateHelper->addClear(IDDIALOG_IDDETAILS, ui->usageStatistics_TB);
mStateHelper->addClear(IDDIALOG_IDDETAILS, ui->label_positive);
mStateHelper->addClear(IDDIALOG_IDDETAILS, ui->label_negative);
//mStateHelper->addWidget(IDDIALOG_REPLIST, ui->treeWidget_RepList); //mStateHelper->addWidget(IDDIALOG_REPLIST, ui->treeWidget_RepList);
//mStateHelper->addLoadPlaceholder(IDDIALOG_REPLIST, ui->treeWidget_RepList); //mStateHelper->addLoadPlaceholder(IDDIALOG_REPLIST, ui->treeWidget_RepList);
@ -221,22 +232,15 @@ IdDialog::IdDialog(QWidget *parent) :
connect(ui->inviteButton, SIGNAL(clicked()), this, SLOT(sendInvite())); connect(ui->inviteButton, SIGNAL(clicked()), this, SLOT(sendInvite()));
ui->avLabel_Person->setPixmap(QPixmap(":/icons/png/people.png"));
ui->avlabel_Circles->setPixmap(QPixmap(":/icons/png/circles.png")); ui->avlabel_Circles->setPixmap(QPixmap(":/icons/png/circles.png"));
ui->headerTextLabel_Person->setText(tr("People"));
ui->headerTextLabel_Circles->setText(tr("Circles")); ui->headerTextLabel_Circles->setText(tr("Circles"));
/* Initialize splitter */ /* Initialize splitter */
ui->mainSplitter->setStretchFactor(0, 0); ui->mainSplitter->setStretchFactor(0, 0);
ui->mainSplitter->setStretchFactor(1, 1); ui->mainSplitter->setStretchFactor(1, 1);
ui->inviteFrame->hide(); clearPerson();
/*remove
QList<int> sizes;
sizes << width() << 500; // Qt calculates the right sizes
ui->splitter->setSizes(sizes);*/
/* Add filter types */ /* Add filter types */
QMenu *idTWHMenu = new QMenu(tr("Show Items"), this); QMenu *idTWHMenu = new QMenu(tr("Show Items"), this);
@ -387,6 +391,21 @@ IdDialog::IdDialog(QWidget *parent) :
tmer->start(10000) ; // update every 10 secs. tmer->start(10000) ; // update every 10 secs.
} }
void IdDialog::clearPerson()
{
QFontMetricsF f(ui->avLabel_Person->font()) ;
ui->avLabel_Person->setPixmap(QPixmap(":/icons/png/people.png").scaled(f.height()*4,f.height()*4,Qt::IgnoreAspectRatio,Qt::SmoothTransformation));
ui->headerTextLabel_Person->setText(tr("People"));
ui->inviteFrame->hide();
ui->avatarLabel->clear();
whileBlocking(ui->ownOpinion_CB)->setCurrentIndex(1);
whileBlocking(ui->autoBanIdentities_CB)->setChecked(false);
}
void IdDialog::toggleAutoBanIdentities(bool b) void IdDialog::toggleAutoBanIdentities(bool b)
{ {
RsPgpId id(ui->lineEdit_GpgId->text().left(16).toStdString()); RsPgpId id(ui->lineEdit_GpgId->text().left(16).toStdString());
@ -1582,9 +1601,9 @@ void IdDialog::insertIdList(uint32_t token)
int accept = filter; int accept = filter;
RsGxsIdGroup data; //RsGxsIdGroup data;
std::vector<RsGxsIdGroup> datavector; std::vector<RsGxsIdGroup> datavector;
std::vector<RsGxsIdGroup>::iterator vit; //std::vector<RsGxsIdGroup>::iterator vit;
if (!rsIdentity->getGroupData(token, datavector)) if (!rsIdentity->getGroupData(token, datavector))
{ {
@ -1595,6 +1614,7 @@ void IdDialog::insertIdList(uint32_t token)
mStateHelper->setActive(IDDIALOG_IDLIST, false); mStateHelper->setActive(IDDIALOG_IDLIST, false);
mStateHelper->clear(IDDIALOG_IDLIST); mStateHelper->clear(IDDIALOG_IDLIST);
clearPerson();
return; return;
} }
@ -1646,7 +1666,7 @@ void IdDialog::insertIdList(uint32_t token)
/* Insert new items */ /* Insert new items */
for (std::map<RsGxsGroupId,RsGxsIdGroup>::const_iterator vit = ids_set.begin(); vit != ids_set.end(); ++vit) for (std::map<RsGxsGroupId,RsGxsIdGroup>::const_iterator vit = ids_set.begin(); vit != ids_set.end(); ++vit)
{ {
data = vit->second ; RsGxsIdGroup data = vit->second ;
item = NULL; item = NULL;
@ -1661,11 +1681,11 @@ void IdDialog::insertIdList(uint32_t token)
Settings->endGroup(); Settings->endGroup();
if (fillIdListItem(vit->second, item, ownPgpId, accept)) if (fillIdListItem(data, item, ownPgpId, accept))
{ {
if(vit->second.mMeta.mSubscribeFlags & GXS_SERV::GROUP_SUBSCRIBE_ADMIN) if(data.mMeta.mSubscribeFlags & GXS_SERV::GROUP_SUBSCRIBE_ADMIN)
ownItem->addChild(item); ownItem->addChild(item);
else if(vit->second.mIsAContact) else if(data.mIsAContact)
contactsItem->addChild(item); contactsItem->addChild(item);
else else
allItem->addChild(item); allItem->addChild(item);
@ -1690,6 +1710,7 @@ void IdDialog::requestIdDetails()
mStateHelper->setActive(IDDIALOG_IDDETAILS, false); mStateHelper->setActive(IDDIALOG_IDDETAILS, false);
mStateHelper->setLoading(IDDIALOG_IDDETAILS, false); mStateHelper->setLoading(IDDIALOG_IDDETAILS, false);
mStateHelper->clear(IDDIALOG_IDDETAILS); mStateHelper->clear(IDDIALOG_IDDETAILS);
clearPerson();
return; return;
} }
@ -1717,6 +1738,7 @@ void IdDialog::insertIdDetails(uint32_t token)
{ {
mStateHelper->setActive(IDDIALOG_IDDETAILS, false); mStateHelper->setActive(IDDIALOG_IDDETAILS, false);
mStateHelper->clear(IDDIALOG_REPLIST); mStateHelper->clear(IDDIALOG_REPLIST);
clearPerson();
ui->lineEdit_KeyId->setText("ERROR GETTING KEY!"); ui->lineEdit_KeyId->setText("ERROR GETTING KEY!");
@ -1731,6 +1753,7 @@ void IdDialog::insertIdDetails(uint32_t token)
mStateHelper->setActive(IDDIALOG_IDDETAILS, false); mStateHelper->setActive(IDDIALOG_IDDETAILS, false);
mStateHelper->clear(IDDIALOG_IDDETAILS); mStateHelper->clear(IDDIALOG_IDDETAILS);
clearPerson();
ui->lineEdit_KeyId->setText("INVALID DV SIZE"); ui->lineEdit_KeyId->setText("INVALID DV SIZE");
@ -1768,8 +1791,14 @@ void IdDialog::insertIdDetails(uint32_t token)
std::cerr << "Setting header frame image : " << pixmap.width() << " x " << pixmap.height() << std::endl; std::cerr << "Setting header frame image : " << pixmap.width() << " x " << pixmap.height() << std::endl;
#endif #endif
ui->avLabel_Person->setPixmap(pixmap); //ui->avLabel_Person->setPixmap(pixmap);
ui->avatarLabel->setPixmap(pixmap); //ui->avatarLabel->setPixmap(pixmap);
QFontMetricsF f(ui->avLabel_Person->font()) ;
ui->avLabel_Person->setPixmap(pixmap.scaled(f.height()*4,f.height()*4,Qt::KeepAspectRatio,Qt::SmoothTransformation));
QFontMetricsF g(ui->inviteButton->font()) ;
ui->avatarLabel->setPixmap(pixmap.scaled(ui->inviteButton->width(),ui->inviteButton->width(),Qt::IgnoreAspectRatio,Qt::SmoothTransformation));
ui->avatarLabel->setScaledContents(true);
if (data.mPgpKnown) if (data.mPgpKnown)
{ {
@ -1813,6 +1842,9 @@ void IdDialog::insertIdDetails(uint32_t token)
if(isOwnId) if(isOwnId)
if (isLinkedToOwnPgpId) if (isLinkedToOwnPgpId)
ui->lineEdit_Type->setText(tr("Identity owned by you, linked to your Retroshare node")) ; ui->lineEdit_Type->setText(tr("Identity owned by you, linked to your Retroshare node")) ;
else
if (data.mMeta.mGroupFlags & (GXS_SERV::FLAG_PRIVACY_PRIVATE | RSGXSID_GROUPFLAG_REALID))
ui->lineEdit_Type->setText(tr("Identity owned by you, linked to your Retroshare node but not yet validated")) ;
else else
ui->lineEdit_Type->setText(tr("Anonymous identity, owned by you")) ; ui->lineEdit_Type->setText(tr("Anonymous identity, owned by you")) ;
else if (data.mMeta.mGroupFlags & RSGXSID_GROUPFLAG_REALID_kept_for_compatibility) else if (data.mMeta.mGroupFlags & RSGXSID_GROUPFLAG_REALID_kept_for_compatibility)

View File

@ -138,6 +138,8 @@ private:
void requestIdEdit(std::string &id); void requestIdEdit(std::string &id);
void showIdEdit(uint32_t token); void showIdEdit(uint32_t token);
void clearPerson();
private: private:
TokenQueue *mIdQueue; TokenQueue *mIdQueue;
TokenQueue *mCircleQueue; TokenQueue *mCircleQueue;

View File

@ -290,6 +290,12 @@
<layout class="QVBoxLayout" name="scrollAreaWidgetContentsVLayout"> <layout class="QVBoxLayout" name="scrollAreaWidgetContentsVLayout">
<item> <item>
<widget class="QFrame" name="headerFramePerson"> <widget class="QFrame" name="headerFramePerson">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Maximum">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="frameShape"> <property name="frameShape">
<enum>QFrame::StyledPanel</enum> <enum>QFrame::StyledPanel</enum>
</property> </property>
@ -477,6 +483,12 @@ border-image: url(:/images/closepressed.png)
</item> </item>
<item row="0" column="0" rowspan="2"> <item row="0" column="0" rowspan="2">
<widget class="QLabel" name="avLabel_Person"> <widget class="QLabel" name="avLabel_Person">
<property name="sizePolicy">
<sizepolicy hsizetype="Maximum" vsizetype="Maximum">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize"> <property name="minimumSize">
<size> <size>
<width>64</width> <width>64</width>
@ -485,8 +497,8 @@ border-image: url(:/images/closepressed.png)
</property> </property>
<property name="maximumSize"> <property name="maximumSize">
<size> <size>
<width>64</width> <width>1000</width>
<height>64</height> <height>1000</height>
</size> </size>
</property> </property>
<property name="styleSheet"> <property name="styleSheet">

View File

@ -227,6 +227,7 @@ void IdEditDialog::enforceNoAnonIds()
{ {
ui->radioButton_GpgId->setChecked(true); ui->radioButton_GpgId->setChecked(true);
ui->radioButton_GpgId->setEnabled(false); ui->radioButton_GpgId->setEnabled(false);
ui->radioButton_Pseudo->setEnabled(false);
} }
void IdEditDialog::loadExistingId(uint32_t token) void IdEditDialog::loadExistingId(uint32_t token)

View File

@ -1027,12 +1027,12 @@ void MainWindow::addFriend()
} }
/** New RSCollection ShortCut */ /** New RSCollection ShortCut */
void MainWindow::newRsCollection() // void MainWindow::newRsCollection()
{ // {
std::vector <DirDetails> dirVec; // std::vector <DirDetails> dirVec;
//
RsCollection(dirVec).openNewColl(this); // RsCollection(dirVec).openNewColl(this);
} // }
/** Shows Share Manager */ /** Shows Share Manager */
void MainWindow::openShareManager() void MainWindow::openShareManager()

View File

@ -223,7 +223,7 @@ private slots:
/** Toolbar fns. */ /** Toolbar fns. */
void addFriend(); void addFriend();
void newRsCollection(); //void newRsCollection();
void showMessengerWindow(); void showMessengerWindow();
void showStatisticsWindow(); void showStatisticsWindow();
#ifdef ENABLE_WEBUI #ifdef ENABLE_WEBUI

View File

@ -231,7 +231,7 @@ MessagesDialog::MessagesDialog(QWidget *parent)
QMenu *printmenu = new QMenu(); QMenu *printmenu = new QMenu();
printmenu->addAction(ui.actionPrint); printmenu->addAction(ui.actionPrint);
printmenu->addAction(ui.actionPrintPreview); printmenu->addAction(ui.actionPrintPreview);
ui.printbutton->setMenu(printmenu); ui.printButton->setMenu(printmenu);
QMenu *viewmenu = new QMenu(); QMenu *viewmenu = new QMenu();
viewmenu->addAction(ui.actionTextBesideIcon); viewmenu->addAction(ui.actionTextBesideIcon);
@ -346,9 +346,8 @@ void MessagesDialog::processSettings(bool load)
} }
// state of splitter // state of splitter
ui.msgSplitter->restoreState(Settings->value("Splitter").toByteArray()); ui.msgSplitter->restoreState(Settings->value("SplitterMsg").toByteArray());
ui.msgSplitter_2->restoreState(Settings->value("Splitter2").toByteArray()); ui.listSplitter->restoreState(Settings->value("SplitterList").toByteArray());
ui.listSplitter->restoreState(Settings->value("Splitter3").toByteArray());
/* toolbar button style */ /* toolbar button style */
Qt::ToolButtonStyle style = (Qt::ToolButtonStyle) Settings->value("ToolButon_Style", Qt::ToolButtonIconOnly).toInt(); Qt::ToolButtonStyle style = (Qt::ToolButtonStyle) Settings->value("ToolButon_Style", Qt::ToolButtonIconOnly).toInt();
@ -361,9 +360,8 @@ void MessagesDialog::processSettings(bool load)
Settings->setValue("MessageTreeVersion", messageTreeVersion); Settings->setValue("MessageTreeVersion", messageTreeVersion);
// state of splitter // state of splitter
Settings->setValue("Splitter", ui.msgSplitter->saveState()); Settings->setValue("SplitterMsg", ui.msgSplitter->saveState());
Settings->setValue("Splitter2", ui.msgSplitter_2->saveState()); Settings->setValue("SplitterList", ui.listSplitter->saveState());
Settings->setValue("Splitter3", ui.listSplitter->saveState());
/* toolbar button style */ /* toolbar button style */
Settings->setValue("ToolButon_Style", ui.newmessageButton->toolButtonStyle()); Settings->setValue("ToolButon_Style", ui.newmessageButton->toolButtonStyle());
@ -1527,8 +1525,8 @@ void MessagesDialog::insertMsgTxtAndFiles(QTreeWidgetItem *item, bool bSetToRead
} }
} }
msgWidget->fill(mCurrMsgId);
updateInterface(); updateInterface();
msgWidget->fill(mCurrMsgId);
} }
bool MessagesDialog::getCurrentMsg(std::string &cid, std::string &mid) bool MessagesDialog::getCurrentMsg(std::string &cid, std::string &mid)
@ -1607,7 +1605,7 @@ void MessagesDialog::setToolbarButtonStyle(Qt::ToolButtonStyle style)
ui.replyallmessageButton->setToolButtonStyle(style); ui.replyallmessageButton->setToolButtonStyle(style);
ui.forwardmessageButton->setToolButtonStyle(style); ui.forwardmessageButton->setToolButtonStyle(style);
ui.tagButton->setToolButtonStyle(style); ui.tagButton->setToolButtonStyle(style);
ui.printbutton->setToolButtonStyle(style); ui.printButton->setToolButtonStyle(style);
ui.viewtoolButton->setToolButtonStyle(style); ui.viewtoolButton->setToolButtonStyle(style);
} }
@ -1710,23 +1708,23 @@ void MessagesDialog::updateMessageSummaryList()
{ {
case ROW_INBOX: case ROW_INBOX:
textTotal = tr("Total:") + " " + QString::number(inboxCount); textTotal = tr("Total:") + " " + QString::number(inboxCount);
ui.total_label->setText(textTotal); ui.totalLabel->setText(textTotal);
break; break;
case ROW_OUTBOX: case ROW_OUTBOX:
textTotal = tr("Total:") + " " + QString::number(newOutboxCount); textTotal = tr("Total:") + " " + QString::number(newOutboxCount);
ui.total_label->setText(textTotal); ui.totalLabel->setText(textTotal);
break; break;
case ROW_DRAFTBOX: case ROW_DRAFTBOX:
textTotal = tr("Total:") + " " + QString::number(newDraftCount); textTotal = tr("Total:") + " " + QString::number(newDraftCount);
ui.total_label->setText(textTotal); ui.totalLabel->setText(textTotal);
break; break;
case ROW_SENTBOX: case ROW_SENTBOX:
textTotal = tr("Total:") + " " + QString::number(newSentboxCount); textTotal = tr("Total:") + " " + QString::number(newSentboxCount);
ui.total_label->setText(textTotal); ui.totalLabel->setText(textTotal);
break; break;
case ROW_TRASHBOX: case ROW_TRASHBOX:
textTotal = tr("Total:") + " " + QString::number(trashboxCount); textTotal = tr("Total:") + " " + QString::number(trashboxCount);
ui.total_label->setText(textTotal); ui.totalLabel->setText(textTotal);
break; break;
} }
@ -1967,7 +1965,7 @@ void MessagesDialog::connectActions()
ui.replymessageButton->disconnect(); ui.replymessageButton->disconnect();
ui.replyallmessageButton->disconnect(); ui.replyallmessageButton->disconnect();
ui.forwardmessageButton->disconnect(); ui.forwardmessageButton->disconnect();
ui.printbutton->disconnect(); ui.printButton->disconnect();
ui.actionPrint->disconnect(); ui.actionPrint->disconnect();
ui.actionPrintPreview->disconnect(); ui.actionPrintPreview->disconnect();
ui.actionSaveAs->disconnect(); ui.actionSaveAs->disconnect();
@ -1994,7 +1992,7 @@ void MessagesDialog::connectActions()
msg->connectAction(MessageWidget::ACTION_REPLY, ui.replymessageButton); msg->connectAction(MessageWidget::ACTION_REPLY, ui.replymessageButton);
msg->connectAction(MessageWidget::ACTION_REPLY_ALL, ui.replyallmessageButton); msg->connectAction(MessageWidget::ACTION_REPLY_ALL, ui.replyallmessageButton);
msg->connectAction(MessageWidget::ACTION_FORWARD, ui.forwardmessageButton); msg->connectAction(MessageWidget::ACTION_FORWARD, ui.forwardmessageButton);
msg->connectAction(MessageWidget::ACTION_PRINT, ui.printbutton); msg->connectAction(MessageWidget::ACTION_PRINT, ui.printButton);
msg->connectAction(MessageWidget::ACTION_PRINT, ui.actionPrint); msg->connectAction(MessageWidget::ACTION_PRINT, ui.actionPrint);
msg->connectAction(MessageWidget::ACTION_PRINT_PREVIEW, ui.actionPrintPreview); msg->connectAction(MessageWidget::ACTION_PRINT_PREVIEW, ui.actionPrintPreview);
msg->connectAction(MessageWidget::ACTION_SAVE_AS, ui.actionSaveAs); msg->connectAction(MessageWidget::ACTION_SAVE_AS, ui.actionSaveAs);
@ -2019,7 +2017,7 @@ void MessagesDialog::updateInterface()
ui.replymessageButton->setEnabled(count == 1); ui.replymessageButton->setEnabled(count == 1);
ui.replyallmessageButton->setEnabled(count == 1); ui.replyallmessageButton->setEnabled(count == 1);
ui.forwardmessageButton->setEnabled(count == 1); ui.forwardmessageButton->setEnabled(count == 1);
ui.printbutton->setEnabled(count == 1); ui.printButton->setEnabled(count == 1);
ui.actionPrint->setEnabled(count == 1); ui.actionPrint->setEnabled(count == 1);
ui.actionPrintPreview->setEnabled(count == 1); ui.actionPrintPreview->setEnabled(count == 1);
ui.actionSaveAs->setEnabled(count == 1); ui.actionSaveAs->setEnabled(count == 1);

View File

@ -49,7 +49,7 @@
<property name="frameShadow"> <property name="frameShadow">
<enum>QFrame::Sunken</enum> <enum>QFrame::Sunken</enum>
</property> </property>
<layout class="QGridLayout" name="gridLayout"> <layout class="QGridLayout" name="toolBarFrameGLayout">
<property name="leftMargin"> <property name="leftMargin">
<number>2</number> <number>2</number>
</property> </property>
@ -66,7 +66,7 @@
<number>6</number> <number>6</number>
</property> </property>
<item row="0" column="9"> <item row="0" column="9">
<widget class="Line" name="line_2"> <widget class="Line" name="toolBarFrameLineR">
<property name="orientation"> <property name="orientation">
<enum>Qt::Vertical</enum> <enum>Qt::Vertical</enum>
</property> </property>
@ -219,7 +219,7 @@
</widget> </widget>
</item> </item>
<item row="0" column="12"> <item row="0" column="12">
<widget class="QToolButton" name="printbutton"> <widget class="QToolButton" name="printButton">
<property name="sizePolicy"> <property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Fixed"> <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
<horstretch>0</horstretch> <horstretch>0</horstretch>
@ -454,7 +454,7 @@
<enum>Qt::NoFocus</enum> <enum>Qt::NoFocus</enum>
</property> </property>
<property name="icon"> <property name="icon">
<iconset resource="images.qrc"> <iconset resource="icons.qrc">
<normaloff>:/icons/help_64.png</normaloff>:/icons/help_64.png</iconset> <normaloff>:/icons/help_64.png</normaloff>:/icons/help_64.png</iconset>
</property> </property>
<property name="checkable"> <property name="checkable">
@ -466,7 +466,7 @@
</widget> </widget>
</item> </item>
<item row="0" column="14"> <item row="0" column="14">
<spacer name="horizontalSpacer"> <spacer name="toolBarFrameSpacerR">
<property name="orientation"> <property name="orientation">
<enum>Qt::Horizontal</enum> <enum>Qt::Horizontal</enum>
</property> </property>
@ -479,7 +479,7 @@
</spacer> </spacer>
</item> </item>
<item row="0" column="2"> <item row="0" column="2">
<spacer name="horizontalSpacer_2"> <spacer name="toolBarFrameSpacerL">
<property name="orientation"> <property name="orientation">
<enum>Qt::Horizontal</enum> <enum>Qt::Horizontal</enum>
</property> </property>
@ -495,7 +495,7 @@
</spacer> </spacer>
</item> </item>
<item row="0" column="5"> <item row="0" column="5">
<widget class="Line" name="line"> <widget class="Line" name="toolBarFrameLineL">
<property name="orientation"> <property name="orientation">
<enum>Qt::Vertical</enum> <enum>Qt::Vertical</enum>
</property> </property>
@ -513,7 +513,7 @@
<attribute name="title"> <attribute name="title">
<string notr="true">Main Tab</string> <string notr="true">Main Tab</string>
</attribute> </attribute>
<layout class="QGridLayout" name="gridLayout_4"> <layout class="QGridLayout" name="tabGLayout">
<property name="leftMargin"> <property name="leftMargin">
<number>0</number> <number>0</number>
</property> </property>
@ -535,7 +535,7 @@
<enum>Qt::Horizontal</enum> <enum>Qt::Horizontal</enum>
</property> </property>
<widget class="QFrame" name="sideBarFrame"> <widget class="QFrame" name="sideBarFrame">
<layout class="QGridLayout" name="gridLayout_3"> <layout class="QGridLayout" name="sideBarFrameGLayout">
<property name="leftMargin"> <property name="leftMargin">
<number>0</number> <number>0</number>
</property> </property>
@ -629,7 +629,7 @@
</widget> </widget>
</item> </item>
<item row="4" column="0"> <item row="4" column="0">
<widget class="QLabel" name="total_label"> <widget class="QLabel" name="totalLabel">
<property name="minimumSize"> <property name="minimumSize">
<size> <size>
<width>0</width> <width>0</width>
@ -646,7 +646,7 @@
<property name="autoFillBackground"> <property name="autoFillBackground">
<bool>true</bool> <bool>true</bool>
</property> </property>
<layout class="QHBoxLayout" name="horizontalLayout_2"> <layout class="QHBoxLayout" name="folderFrameHLayout">
<property name="topMargin"> <property name="topMargin">
<number>3</number> <number>3</number>
</property> </property>
@ -687,7 +687,7 @@
<property name="frameShadow"> <property name="frameShadow">
<enum>QFrame::Raised</enum> <enum>QFrame::Raised</enum>
</property> </property>
<layout class="QHBoxLayout" name="horizontalLayout_3"> <layout class="QHBoxLayout" name="quickViewFrameHLayout">
<property name="topMargin"> <property name="topMargin">
<number>3</number> <number>3</number>
</property> </property>
@ -723,10 +723,6 @@
</layout> </layout>
</widget> </widget>
<widget class="QSplitter" name="msgSplitter"> <widget class="QSplitter" name="msgSplitter">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<widget class="QSplitter" name="msgSplitter_2">
<property name="orientation"> <property name="orientation">
<enum>Qt::Vertical</enum> <enum>Qt::Vertical</enum>
</property> </property>
@ -760,7 +756,6 @@
</widget> </widget>
</widget> </widget>
</widget> </widget>
</widget>
</item> </item>
</layout> </layout>
</widget> </widget>
@ -838,6 +833,11 @@
</action> </action>
</widget> </widget>
<customwidgets> <customwidgets>
<customwidget>
<class>StyledLabel</class>
<extends>QLabel</extends>
<header>gui/common/StyledLabel.h</header>
</customwidget>
<customwidget> <customwidget>
<class>LineEditClear</class> <class>LineEditClear</class>
<extends>QLineEdit</extends> <extends>QLineEdit</extends>
@ -854,19 +854,14 @@
<header>gui/common/RSTabWidget.h</header> <header>gui/common/RSTabWidget.h</header>
<container>1</container> <container>1</container>
</customwidget> </customwidget>
<customwidget>
<class>StyledLabel</class>
<extends>QLabel</extends>
<header>gui/common/StyledLabel.h</header>
</customwidget>
</customwidgets> </customwidgets>
<tabstops> <tabstops>
<tabstop>replymessageButton</tabstop> <tabstop>replymessageButton</tabstop>
<tabstop>listWidget</tabstop> <tabstop>listWidget</tabstop>
</tabstops> </tabstops>
<resources> <resources>
<include location="images.qrc"/>
<include location="icons.qrc"/> <include location="icons.qrc"/>
<include location="images.qrc"/>
</resources> </resources>
<connections/> <connections/>
</ui> </ui>

View File

@ -58,108 +58,90 @@
#define IMAGE_MESSAGE ":/images/mail_new.png" #define IMAGE_MESSAGE ":/images/mail_new.png"
/* Images for Status icons */ /* Images for Status icons */
#define IMAGE_AUTHED ":/images/accepted16.png"
//following defined in model
/*#define IMAGE_AUTHED ":/images/accepted16.png"
#define IMAGE_DENIED ":/images/denied16.png" #define IMAGE_DENIED ":/images/denied16.png"
#define IMAGE_TRUSTED ":/images/rs-2.png" #define IMAGE_TRUSTED ":/images/rs-2.png" */
// Defines for key list columns // Defines for key list columns
#define COLUMN_CHECK 0
//following defined in model
/*#define COLUMN_CHECK 0
#define COLUMN_PEERNAME 1 #define COLUMN_PEERNAME 1
#define COLUMN_I_AUTH_PEER 2 #define COLUMN_I_AUTH_PEER 2
#define COLUMN_PEER_AUTH_ME 3 #define COLUMN_PEER_AUTH_ME 3
#define COLUMN_PEERID 4 #define COLUMN_PEERID 4
#define COLUMN_LAST_USED 5 #define COLUMN_LAST_USED 5
#define COLUMN_COUNT 6 #define COLUMN_COUNT 6 */
RsPeerId getNeighRsCertId(QTreeWidgetItem *i); //RsPeerId getNeighRsCertId(QTreeWidgetItem *i);
/****** /******
* #define NET_DEBUG 1 * #define NET_DEBUG 1
*****/ *****/
static const unsigned int ROLE_SORT = Qt::UserRole + 1 ; //static const unsigned int ROLE_SORT = Qt::UserRole + 1 ;
/** Constructor */ /** Constructor */
NetworkDialog::NetworkDialog(QWidget *parent) NetworkDialog::NetworkDialog(QWidget *parent)
: RsAutoUpdatePage(10000,parent) // updates every 10 sec.
{ {
/* Invoke the Qt Designer generated object setup routine */ /* Invoke the Qt Designer generated object setup routine */
Q_UNUSED(parent);
ui.setupUi(this); ui.setupUi(this);
connect( ui.connectTreeWidget, SIGNAL( customContextMenuRequested( QPoint ) ), this, SLOT( connectTreeWidgetCostumPopupMenu( QPoint ) ) );
connect( ui.connectTreeWidget, SIGNAL( itemDoubleClicked(QTreeWidgetItem*,int)), this, SLOT( peerdetails () ) );
connect( ui.filterLineEdit, SIGNAL(textChanged(const QString &)), this, SLOT(filterItems(QString))); connect( ui.filterLineEdit, SIGNAL(textChanged(const QString &)), this, SLOT(filterItems(QString)));
connect( ui.filterLineEdit, SIGNAL(filterChanged(int)), this, SLOT(filterColumnChanged(int))); connect( ui.filterLineEdit, SIGNAL(filterChanged(int)), this, SLOT(filterColumnChanged(int)));
connect( ui.onlyTrustedKeys, SIGNAL(clicked()), this, SLOT(securedUpdateDisplay()));
/* hide the Tree +/- */ //list data model
ui.connectTreeWidget -> setRootIsDecorated( false ); float f = QFontMetricsF(font()).height()/14.0 ;
ui.connectTreeWidget -> setColumnCount(6);
compareNetworkRole = new RSTreeWidgetItemCompareRole; PGPIdItemModel = new pgpid_item_model(neighs, f, this);
compareNetworkRole->setRole(COLUMN_LAST_USED, ROLE_SORT); PGPIdItemProxy = new pgpid_item_proxy(this);
connect(ui.onlyTrustedKeys, SIGNAL(toggled(bool)), PGPIdItemProxy, SLOT(use_only_trusted_keys(bool)));
PGPIdItemProxy->setSourceModel(PGPIdItemModel);
PGPIdItemProxy->setFilterKeyColumn(COLUMN_PEERNAME);
PGPIdItemProxy->setFilterCaseSensitivity(Qt::CaseInsensitive);
PGPIdItemProxy->setSortRole(Qt::EditRole); //use edit role to get raw data since we do not have edit for this model.
ui.connectTreeWidget->setModel(PGPIdItemProxy);
ui.connectTreeWidget->setContextMenuPolicy(Qt::CustomContextMenu);
ui.connectTreeWidget->verticalHeader()->hide();
ui.connectTreeWidget->setShowGrid(false);
ui.connectTreeWidget->setUpdatesEnabled(true);
ui.connectTreeWidget->setSortingEnabled(true);
ui.connectTreeWidget->setSelectionBehavior(QAbstractItemView::SelectRows);
ui.connectTreeWidget->setSelectionMode(QAbstractItemView::SingleSelection);
connect(ui.connectTreeWidget, SIGNAL( customContextMenuRequested( QPoint ) ), this, SLOT( connectTreeWidgetCostumPopupMenu( QPoint ) ) );
connect(ui.connectTreeWidget, SIGNAL(doubleClicked(QModelIndex)), this, SLOT(peerdetails()));
/* Set header resize modes and initial section sizes */ /* Set header resize modes and initial section sizes */
QHeaderView * _header = ui.connectTreeWidget->header () ; /* QHeaderView * _header = ui.connectTreeWidget->header () ;
QHeaderView_setSectionResizeModeColumn(_header, COLUMN_CHECK, QHeaderView::Custom); QHeaderView_setSectionResizeModeColumn(_header, COLUMN_CHECK, QHeaderView::Custom);
QHeaderView_setSectionResizeModeColumn(_header, COLUMN_PEERNAME, QHeaderView::Interactive); QHeaderView_setSectionResizeModeColumn(_header, COLUMN_PEERNAME, QHeaderView::Interactive);
QHeaderView_setSectionResizeModeColumn(_header, COLUMN_I_AUTH_PEER, QHeaderView::Interactive); QHeaderView_setSectionResizeModeColumn(_header, COLUMN_I_AUTH_PEER, QHeaderView::Interactive);
QHeaderView_setSectionResizeModeColumn(_header, COLUMN_PEER_AUTH_ME, QHeaderView::Interactive); QHeaderView_setSectionResizeModeColumn(_header, COLUMN_PEER_AUTH_ME, QHeaderView::Interactive);
QHeaderView_setSectionResizeModeColumn(_header, COLUMN_PEERID, QHeaderView::Interactive); QHeaderView_setSectionResizeModeColumn(_header, COLUMN_PEERID, QHeaderView::Interactive);
QHeaderView_setSectionResizeModeColumn(_header, COLUMN_LAST_USED, QHeaderView::Interactive); QHeaderView_setSectionResizeModeColumn(_header, COLUMN_LAST_USED, QHeaderView::Interactive); */
_header->model()->setHeaderData(COLUMN_CHECK, Qt::Horizontal, tr(""));
_header->model()->setHeaderData(COLUMN_PEERNAME, Qt::Horizontal, tr("Profile"));
_header->model()->setHeaderData(COLUMN_I_AUTH_PEER, Qt::Horizontal, tr("Trust level"));
_header->model()->setHeaderData(COLUMN_PEER_AUTH_ME, Qt::Horizontal, tr("Has signed your key?"));
_header->model()->setHeaderData(COLUMN_PEERID, Qt::Horizontal, tr("Id"));
_header->model()->setHeaderData(COLUMN_LAST_USED, Qt::Horizontal, tr("Last used"));
_header->model()->setHeaderData(COLUMN_CHECK, Qt::Horizontal, tr(" Do you accept connections signed by this profile?"),Qt::ToolTipRole);
_header->model()->setHeaderData(COLUMN_PEERNAME, Qt::Horizontal, tr("Name of the profile"),Qt::ToolTipRole);
_header->model()->setHeaderData(COLUMN_I_AUTH_PEER, Qt::Horizontal, tr("This column indicates trust level and whether you signed the profile PGP key"),Qt::ToolTipRole);
_header->model()->setHeaderData(COLUMN_PEER_AUTH_ME, Qt::Horizontal, tr("Did that peer sign your own profile PGP key"),Qt::ToolTipRole);
_header->model()->setHeaderData(COLUMN_PEERID, Qt::Horizontal, tr("PGP Key Id of that profile"),Qt::ToolTipRole);
_header->model()->setHeaderData(COLUMN_LAST_USED, Qt::Horizontal, tr("Last time this key was used (received time, or to check connection)"),Qt::ToolTipRole);
float f = QFontMetricsF(font()).height()/14.0 ;
_header->resizeSection ( COLUMN_CHECK, 25*f );
_header->resizeSection ( COLUMN_PEERNAME, 200*f );
_header->resizeSection ( COLUMN_I_AUTH_PEER, 200*f );
_header->resizeSection ( COLUMN_PEER_AUTH_ME, 200*f );
_header->resizeSection ( COLUMN_LAST_USED, 75*f );
// set header text aligment
QTreeWidgetItem * headerItem = ui.connectTreeWidget->headerItem();
headerItem->setTextAlignment(COLUMN_CHECK, Qt::AlignHCenter | Qt::AlignVCenter);
headerItem->setTextAlignment(COLUMN_PEERNAME, Qt::AlignHCenter | Qt::AlignVCenter);
headerItem->setTextAlignment(COLUMN_I_AUTH_PEER, Qt::AlignHCenter | Qt::AlignVCenter);
headerItem->setTextAlignment(COLUMN_PEER_AUTH_ME, Qt::AlignHCenter | Qt::AlignVCenter);
headerItem->setTextAlignment(COLUMN_PEERID, Qt::AlignVCenter);
headerItem->setTextAlignment(COLUMN_LAST_USED, Qt::AlignVCenter);
headerItem->setText(0,QString()) ;
ui.connectTreeWidget->sortItems( COLUMN_PEERNAME, Qt::AscendingOrder );
ui.onlyTrustedKeys->setMinimumWidth(20*f); ui.onlyTrustedKeys->setMinimumWidth(20*f);
QMenu *menu = new QMenu(); /* QMenu *menu = new QMenu();
menu->addAction(ui.actionTabsright); menu->addAction(ui.actionTabsright);
menu->addAction(ui.actionTabswest); menu->addAction(ui.actionTabswest);
menu->addAction(ui.actionTabssouth); menu->addAction(ui.actionTabssouth);
menu->addAction(ui.actionTabsnorth); menu->addAction(ui.actionTabsnorth);
menu->addSeparator(); menu->addSeparator();
menu->addAction(ui.actionTabsTriangular); menu->addAction(ui.actionTabsTriangular);
menu->addAction(ui.actionTabsRounded); menu->addAction(ui.actionTabsRounded); */
/* add filter actions */ /* add filter actions */
ui.filterLineEdit->addFilter(QIcon(), tr("Name"), COLUMN_PEERNAME, tr("Search name")); ui.filterLineEdit->addFilter(QIcon(), tr("Name"), COLUMN_PEERNAME, tr("Search name"));
ui.filterLineEdit->addFilter(QIcon(), tr("Peer ID"), COLUMN_PEERID, tr("Search peer ID")); ui.filterLineEdit->addFilter(QIcon(), tr("Peer ID"), COLUMN_PEERID, tr("Search peer ID"));
ui.filterLineEdit->setCurrentFilter(COLUMN_PEERNAME); ui.filterLineEdit->setCurrentFilter(COLUMN_PEERNAME);
connect(ui.filterLineEdit, SIGNAL(textChanged(QString)), PGPIdItemProxy, SLOT(setFilterWildcard(QString)));
} }
void NetworkDialog::changeEvent(QEvent *e) void NetworkDialog::changeEvent(QEvent *e)
@ -177,14 +159,16 @@ void NetworkDialog::changeEvent(QEvent *e)
void NetworkDialog::connectTreeWidgetCostumPopupMenu( QPoint /*point*/ ) void NetworkDialog::connectTreeWidgetCostumPopupMenu( QPoint /*point*/ )
{ {
//std::cerr << "NetworkDialog::connectTreeWidgetCostumPopupMenu( QPoint point ) called" << std::endl;
QTreeWidgetItem *wi = getCurrentNeighbour(); QModelIndexList l = ui.connectTreeWidget->selectionModel()->selection().indexes();
if (!wi) if(l.empty())
{
return; return;
}
QMenu *contextMnu = new QMenu; QMenu *contextMnu = new QMenu;
RsPgpId peer_id(wi->text(COLUMN_PEERID).toStdString()) ; RsPgpId peer_id(ui.connectTreeWidget->model()->data(ui.connectTreeWidget->model()->index(l.begin()->row(), COLUMN_PEERID)).toString().toStdString()) ;
// That's what context menus are made for // That's what context menus are made for
RsPeerDetails detail; RsPeerDetails detail;
@ -271,13 +255,17 @@ void NetworkDialog::removeUnusedKeys()
} }
QMessageBox::warning(NULL,tr("Keyring info"),tr("Key removal has failed. Your keyring remains intact.\n\nReported error:")+" "+error_string ) ; QMessageBox::warning(NULL,tr("Keyring info"),tr("Key removal has failed. Your keyring remains intact.\n\nReported error:")+" "+error_string ) ;
} }
insertConnect() ; updateDisplay();
// insertConnect() ;
} }
void NetworkDialog::denyFriend() void NetworkDialog::denyFriend()
{ {
QTreeWidgetItem *wi = getCurrentNeighbour(); QModelIndexList l = ui.connectTreeWidget->selectionModel()->selection().indexes();
RsPgpId peer_id( wi->text(COLUMN_PEERID).toStdString() ); if(l.empty())
return;
RsPgpId peer_id(ui.connectTreeWidget->model()->data(ui.connectTreeWidget->model()->index(l.begin()->row(), COLUMN_PEERID)).toString().toStdString());
rsPeers->removeFriend(peer_id) ; rsPeers->removeFriend(peer_id) ;
securedUpdateDisplay(); securedUpdateDisplay();
@ -300,27 +288,32 @@ void NetworkDialog::denyFriend()
void NetworkDialog::makeFriend() void NetworkDialog::makeFriend()
{ {
PGPKeyDialog::showIt(RsPgpId(getCurrentNeighbour()->text(COLUMN_PEERID).toStdString()), PGPKeyDialog::PageDetails);
QModelIndexList l = ui.connectTreeWidget->selectionModel()->selection().indexes();
if(l.empty())
return;
PGPKeyDialog::showIt(RsPgpId(ui.connectTreeWidget->model()->data(ui.connectTreeWidget->model()->index(l.begin()->row(), COLUMN_PEERID)).toString().toStdString()), PGPKeyDialog::PageDetails);
} }
/** Shows Peer Information/Auth Dialog */ /** Shows Peer Information/Auth Dialog */
void NetworkDialog::peerdetails() void NetworkDialog::peerdetails()
{ {
QTreeWidgetItem* item = getCurrentNeighbour(); QModelIndexList l = ui.connectTreeWidget->selectionModel()->selection().indexes();
if (item == NULL) { if(l.empty())
return; return;
}
PGPKeyDialog::showIt(RsPgpId(item->text(COLUMN_PEERID).toStdString()), PGPKeyDialog::PageDetails); PGPKeyDialog::showIt(RsPgpId(ui.connectTreeWidget->model()->data(ui.connectTreeWidget->model()->index(l.begin()->row(), COLUMN_PEERID)).toString().toStdString()), PGPKeyDialog::PageDetails);
} }
void NetworkDialog::copyLink() void NetworkDialog::copyLink()
{ {
QTreeWidgetItem *wi = getCurrentNeighbour(); QModelIndexList l = ui.connectTreeWidget->selectionModel()->selection().indexes();
if (wi == NULL) { if(l.empty())
return; return;
}
RsPgpId peer_id ( wi->text(COLUMN_PEERID).toStdString() ) ;
RsPgpId peer_id (ui.connectTreeWidget->model()->data(ui.connectTreeWidget->model()->index(l.begin()->row(), COLUMN_PEERID)).toString().toStdString()) ;
QList<RetroShareLink> urls; QList<RetroShareLink> urls;
RetroShareLink link = RetroShareLink::createPerson(peer_id); RetroShareLink link = RetroShareLink::createPerson(peer_id);
@ -356,225 +349,14 @@ void NetworkDialog::copyLink()
// /* window will destroy itself! */ // /* window will destroy itself! */
//} //}
void NetworkDialog::updateDisplay()
{
insertConnect() ;
}
/* get the list of Neighbours from the RsIface. */
void NetworkDialog::insertConnect()
{
// static time_t last_time = 0 ;
if (!rsPeers)
return;
// // Because this is called from a qt signal, there's no limitation between calls.
time_t now = time(NULL);
std::list<RsPgpId> neighs; //these are GPG ids
std::list<RsPgpId>::iterator it;
rsPeers->getGPGAllList(neighs);
/* get a link to the table */
QTreeWidget *connectWidget = ui.connectTreeWidget;
/* disable sorting while editing the table */
connectWidget->setSortingEnabled(false);
//remove items
int index = 0;
while (index < connectWidget->topLevelItemCount())
{
RsPgpId gpg_widget_id( (connectWidget->topLevelItem(index))->text(COLUMN_PEERID).toStdString() );
RsPeerDetails detail;
if ( (!rsPeers->getGPGDetails(gpg_widget_id, detail)) || (ui.onlyTrustedKeys->isChecked() && (detail.validLvl < RS_TRUST_LVL_MARGINAL && !detail.accept_connection)))
delete (connectWidget->takeTopLevelItem(index));
else
++index;
}
for(it = neighs.begin(); it != neighs.end(); ++it)
{
#ifdef NET_DEBUG
std::cerr << "NetworkDialog::insertConnect() inserting gpg key : " << *it << std::endl;
#endif
if (*it == rsPeers->getGPGOwnId()) {
continue;
}
RsPeerDetails detail;
if (!rsPeers->getGPGDetails(*it, detail))
{
continue; /* BAD */
}
/* make a widget per friend */
QTreeWidgetItem *item;
QList<QTreeWidgetItem *> list = connectWidget->findItems(QString::fromStdString( (*it).toStdString() ), Qt::MatchExactly, COLUMN_PEERID);
if (list.size() == 1) {
item = list.front();
} else {
//create new item
#ifdef NET_DEBUG
std::cerr << "NetworkDialog::insertConnect() creating new tree widget item : " << *it << std::endl;
#endif
item = new RSTreeWidgetItem(compareNetworkRole, 0);
item -> setChildIndicatorPolicy(QTreeWidgetItem::DontShowIndicatorWhenChildless);
int S = QFontMetricsF(font()).height() ;
item -> setSizeHint(COLUMN_CHECK, QSize( S,S ) );
/* (1) Person */
item -> setText(COLUMN_PEERNAME, QString::fromUtf8(detail.name.c_str()));
/* (4) key id */
item -> setText(COLUMN_PEERID, QString::fromStdString(detail.gpg_id.toStdString()));
}
//QString TrustLevelString ;
/* (2) Key validity */
if (detail.ownsign)
{
item -> setText(COLUMN_I_AUTH_PEER, tr("Personal signature"));
item -> setToolTip(COLUMN_I_AUTH_PEER, tr("PGP key signed by you"));
}
else
switch(detail.trustLvl)
{
case RS_TRUST_LVL_MARGINAL: item->setText(COLUMN_I_AUTH_PEER,tr("Marginally trusted peer")) ; break;
case RS_TRUST_LVL_FULL:
case RS_TRUST_LVL_ULTIMATE: item->setText(COLUMN_I_AUTH_PEER,tr("Fully trusted peer")) ; break ;
case RS_TRUST_LVL_UNKNOWN:
case RS_TRUST_LVL_UNDEFINED:
case RS_TRUST_LVL_NEVER:
default: item->setText(2,tr("Untrusted peer")) ; break ;
}
/* (3) has me auth */
QString PeerAuthenticationString ;
if (detail.hasSignedMe)
PeerAuthenticationString = tr("Yes");
else
PeerAuthenticationString = tr("No");
item->setText(COLUMN_PEER_AUTH_ME,PeerAuthenticationString) ;
uint64_t last_time_used = now - detail.lastUsed ;
QString lst_used_str ;
if(last_time_used < 3600)
lst_used_str = tr("Last hour") ;
else if(last_time_used < 86400)
lst_used_str = tr("Today") ;
else if(last_time_used > 86400 * 15000)
lst_used_str = tr("Never");
else
lst_used_str = tr("%1 days ago").arg((int)( last_time_used / 86400 )) ;
QString lst_used_sort_str = QString::number(detail.lastUsed,'f',10);
item->setText(COLUMN_LAST_USED,lst_used_str) ;
item->setData(COLUMN_LAST_USED,ROLE_SORT,lst_used_sort_str) ;
/**
* Determinated the Background Color
*/
QColor backgrndcolor;
if (detail.accept_connection)
{
item -> setText(COLUMN_CHECK, "0");
item -> setIcon(COLUMN_CHECK,(QIcon(IMAGE_AUTHED)));
if (detail.ownsign)
{
backgrndcolor = backgroundColorOwnSign();
}
else
{
backgrndcolor = backgroundColorAcceptConnection();
}
}
else
{
item -> setText(COLUMN_CHECK, "1");
if (detail.hasSignedMe)
{
backgrndcolor = backgroundColorHasSignedMe();
item -> setIcon(COLUMN_CHECK,(QIcon(IMAGE_DENIED)));
for(int k=0;k<COLUMN_COUNT;++k)
item -> setToolTip(k, QString::fromUtf8(detail.name.c_str()) + tr(" has authenticated you. \nRight-click and select 'make friend' to be able to connect."));
}
else
{
backgrndcolor = backgroundColorDenied();
item -> setIcon(COLUMN_CHECK,(QIcon(IMAGE_DENIED)));
}
}
// Color each Background column in the Network Tab except the first one => 1-9
// whith the determinated color
for(int i = 0; i <COLUMN_COUNT; ++i)
item -> setBackground(i,QBrush(backgrndcolor));
if( (detail.accept_connection || detail.validLvl >= RS_TRUST_LVL_MARGINAL) || !ui.onlyTrustedKeys->isChecked())
connectWidget->addTopLevelItem(item);
}
// add self to network.
RsPeerDetails ownGPGDetails;
rsPeers->getGPGDetails(rsPeers->getGPGOwnId(), ownGPGDetails);
/* make a widget per friend */
QTreeWidgetItem *self_item;
QList<QTreeWidgetItem *> list = connectWidget->findItems(QString::fromStdString(ownGPGDetails.gpg_id.toStdString()), Qt::MatchExactly, COLUMN_PEERID);
if (list.size() == 1) {
self_item = list.front();
} else {
self_item = new RSTreeWidgetItem(compareNetworkRole, 0);
self_item->setChildIndicatorPolicy(QTreeWidgetItem::DontShowIndicatorWhenChildless);
}
self_item -> setText(COLUMN_CHECK, "0");
self_item->setIcon(COLUMN_CHECK,(QIcon(IMAGE_AUTHED)));
self_item->setText(COLUMN_PEERNAME, QString::fromUtf8(ownGPGDetails.name.c_str()) + " (" + tr("yourself") + ")");
self_item->setText(COLUMN_I_AUTH_PEER,"N/A");
self_item->setText(COLUMN_PEERID, QString::fromStdString(ownGPGDetails.gpg_id.toStdString()));
// Color each Background column in the Network Tab except the first one => 1-9
for(int i=0;i<COLUMN_COUNT;++i)
{
self_item->setBackground(i,backgroundColorSelf()) ;
}
connectWidget->addTopLevelItem(self_item);
/* enable sorting */
connectWidget->setSortingEnabled(true);
/* update display */
connectWidget->update();
if (ui.filterLineEdit->text().isEmpty() == false) {
filterItems(ui.filterLineEdit->text());
}
}
QTreeWidgetItem *NetworkDialog::getCurrentNeighbour()
{
if (ui.connectTreeWidget->selectedItems().size() != 0)
{
return ui.connectTreeWidget -> currentItem();
}
return NULL;
}
/* Utility Fns */ /* Utility Fns */
RsPeerId getNeighRsCertId(QTreeWidgetItem *i) /*RsPeerId getNeighRsCertId(QTreeWidgetItem *i)
{ {
RsPeerId id ( (i -> text(COLUMN_PEERID)).toStdString() ); RsPeerId id ( (i -> text(COLUMN_PEERID)).toStdString() );
return id; return id;
} } */
void NetworkDialog::on_actionAddFriend_activated() void NetworkDialog::on_actionAddFriend_activated()
{ {
// /* Create a new input dialog, which allows users to create files, too */ // /* Create a new input dialog, which allows users to create files, too */
@ -700,44 +482,23 @@ void NetworkDialog::on_actionCreate_New_Profile_activated()
// Settings->endGroup(); // Settings->endGroup();
// } // }
void NetworkDialog::filterColumnChanged(int) void NetworkDialog::filterColumnChanged(int col)
{ {
filterItems(ui.filterLineEdit->text()); if(PGPIdItemProxy)
PGPIdItemProxy->setFilterKeyColumn(col);
//filterItems(ui.filterLineEdit->text());
} }
void NetworkDialog::filterItems(const QString &text)
void NetworkDialog::updateDisplay()
{ {
int filterColumn = ui.filterLineEdit->currentFilter(); if (!rsPeers)
return;
int count = ui.connectTreeWidget->topLevelItemCount (); //update ids list
for (int index = 0; index < count; ++index) { std::list<RsPgpId> new_neighs;
filterItem(ui.connectTreeWidget->topLevelItem(index), text, filterColumn); rsPeers->getGPGAllList(new_neighs);
} //refresh model
PGPIdItemModel->data_updated(new_neighs);
} }
bool NetworkDialog::filterItem(QTreeWidgetItem *item, const QString &text, int filterColumn)
{
bool visible = true;
if (text.isEmpty() == false) {
if (item->text(filterColumn).contains(text, Qt::CaseInsensitive) == false) {
visible = false;
}
}
int visibleChildCount = 0;
int count = item->childCount();
for (int index = 0; index < count; ++index) {
if (filterItem(item->child(index), text, filterColumn)) {
++visibleChildCount;
}
}
if (visible || visibleChildCount) {
item->setHidden(false);
} else {
item->setHidden(true);
}
return (visible || visibleChildCount);
}

View File

@ -25,9 +25,15 @@
#include "ui_NetworkDialog.h" #include "ui_NetworkDialog.h"
#include "RsAutoUpdatePage.h" #include "RsAutoUpdatePage.h"
#include "gui/NetworkDialog/pgpid_item_model.h"
#include "gui/NetworkDialog/pgpid_item_proxy.h"
//tmp
class QTreeWidgetItem;
class RSTreeWidgetItemCompareRole ; class RSTreeWidgetItemCompareRole ;
class NetworkDialog : public RsAutoUpdatePage class NetworkDialog : public RsAutoUpdatePage
{ {
Q_OBJECT Q_OBJECT
@ -42,7 +48,6 @@ public:
/** Default Constructor */ /** Default Constructor */
NetworkDialog(QWidget *parent = 0); NetworkDialog(QWidget *parent = 0);
//void load();
virtual void updateDisplay() ; // overloaded from RsAutoUpdatePage virtual void updateDisplay() ; // overloaded from RsAutoUpdatePage
QColor backgroundColorSelf() const { return mBackgroundColorSelf; } QColor backgroundColorSelf() const { return mBackgroundColorSelf; }
@ -51,14 +56,14 @@ public:
QColor backgroundColorHasSignedMe() const { return mBackgroundColorHasSignedMe; } QColor backgroundColorHasSignedMe() const { return mBackgroundColorHasSignedMe; }
QColor backgroundColorDenied() const { return mBackgroundColorDenied; } QColor backgroundColorDenied() const { return mBackgroundColorDenied; }
void setBackgroundColorSelf(QColor color) { mBackgroundColorSelf = color; } void setBackgroundColorSelf(QColor color) { PGPIdItemModel->setBackgroundColorSelf(color); mBackgroundColorSelf = color; }
void setBackgroundColorOwnSign(QColor color) { mBackgroundColorOwnSign = color; } void setBackgroundColorOwnSign(QColor color) { PGPIdItemModel->setBackgroundColorOwnSign(color); mBackgroundColorOwnSign = color; }
void setBackgroundColorAcceptConnection(QColor color) { mBackgroundColorAcceptConnection = color; } void setBackgroundColorAcceptConnection(QColor color) { PGPIdItemModel->setBackgroundColorAcceptConnection(color); mBackgroundColorAcceptConnection = color; }
void setBackgroundColorHasSignedMe(QColor color) { mBackgroundColorHasSignedMe = color; } void setBackgroundColorHasSignedMe(QColor color) { PGPIdItemModel->setBackgroundColorHasSignedMe(color); mBackgroundColorHasSignedMe = color; }
void setBackgroundColorDenied(QColor color) { mBackgroundColorDenied = color; } void setBackgroundColorDenied(QColor color) { PGPIdItemModel->setBackgroundColorDenied(color); mBackgroundColorDenied = color; }
private: private:
void insertConnect(); // void insertConnect();
// std::string loadneighbour(); // std::string loadneighbour();
/* void loadneighbour(); */ /* void loadneighbour(); */
//void updateNewDiscoveryInfo() ; //void updateNewDiscoveryInfo() ;
@ -104,14 +109,15 @@ private slots:
// void on_actionTabsTriangular_activated(); // void on_actionTabsTriangular_activated();
void filterColumnChanged(int); void filterColumnChanged(int);
void filterItems(const QString &text); // void filterItems(const QString &text);
private: private:
QTreeWidgetItem *getCurrentNeighbour();
// class NetworkView *networkview; // class NetworkView *networkview;
bool filterItem(QTreeWidgetItem *item, const QString &text, int filterColumn); // bool filterItem(QTreeWidgetItem *item, const QString &text, int filterColumn);
/* Color definitions (for standard see qss.default) */ /* Color definitions (for standard see qss.default) */
QColor mBackgroundColorSelf; QColor mBackgroundColorSelf;
@ -122,6 +128,12 @@ private:
RSTreeWidgetItemCompareRole *compareNetworkRole ; RSTreeWidgetItemCompareRole *compareNetworkRole ;
//iinternal long lived data
std::list<RsPgpId> neighs;
pgpid_item_model *PGPIdItemModel;
pgpid_item_proxy *PGPIdItemProxy;
/** Qt Designer generated object */ /** Qt Designer generated object */
Ui::NetworkDialog ui; Ui::NetworkDialog ui;
}; };

View File

@ -41,7 +41,7 @@
<property name="orientation"> <property name="orientation">
<enum>Qt::Vertical</enum> <enum>Qt::Vertical</enum>
</property> </property>
<widget class="QTreeWidget" name="connectTreeWidget"> <widget class="QTableView" name="connectTreeWidget">
<property name="sizePolicy"> <property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Expanding"> <sizepolicy hsizetype="Expanding" vsizetype="Expanding">
<horstretch>0</horstretch> <horstretch>0</horstretch>
@ -66,63 +66,6 @@
<height>16</height> <height>16</height>
</size> </size>
</property> </property>
<property name="uniformRowHeights">
<bool>true</bool>
</property>
<property name="sortingEnabled">
<bool>true</bool>
</property>
<property name="animated">
<bool>true</bool>
</property>
<property name="allColumnsShowFocus">
<bool>true</bool>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
<attribute name="headerCascadingSectionResizes">
<bool>true</bool>
</attribute>
<attribute name="headerDefaultSectionSize">
<number>200</number>
</attribute>
<attribute name="headerStretchLastSection">
<bool>true</bool>
</attribute>
<column>
<property name="text">
<string/>
</property>
</column>
<column>
<property name="text">
<string>Profile</string>
</property>
</column>
<column>
<property name="text">
<string>Did I authenticated peer</string>
</property>
<property name="toolTip">
<string>Did I sign his PGP key</string>
</property>
</column>
<column>
<property name="text">
<string>Has signed my key</string>
</property>
</column>
<column>
<property name="text">
<string>Cert Id</string>
</property>
</column>
<column>
<property name="text">
<string>Last used</string>
</property>
</column>
</widget> </widget>
</widget> </widget>
</item> </item>

View File

@ -0,0 +1,348 @@
#include "pgpid_item_model.h"
#include <time.h>
#include <retroshare/rspeers.h>
#include <QIcon>
#include <QBrush>
/*TODO:
* using list here for internal data storage is not best option
*/
pgpid_item_model::pgpid_item_model(std::list<RsPgpId> &neighs_, float &_font_height, QObject *parent)
: QAbstractTableModel(parent), neighs(neighs_), font_height(_font_height)
{
}
QVariant pgpid_item_model::headerData(int section, Qt::Orientation orientation, int role) const
{
if(orientation == Qt::Horizontal)
{
if(role == Qt::ToolTipRole)
{
switch(section)
{
case COLUMN_CHECK:
return QString(tr(" Do you accept connections signed by this profile?"));
break;
case COLUMN_PEERNAME:
return QString(tr("Name of the profile"));
break;
case COLUMN_I_AUTH_PEER:
return QString(tr("This column indicates trust level and whether you signed the profile PGP key"));
break;
case COLUMN_PEER_AUTH_ME:
return QString(tr("Did that peer sign your own profile PGP key"));
break;
case COLUMN_PEERID:
return QString(tr("PGP Key Id of that profile"));
break;
case COLUMN_LAST_USED:
return QString(tr("Last time this key was used (received time, or to check connection)"));
break;
}
}
else if(role == Qt::DisplayRole)
{
switch(section)
{
case COLUMN_CHECK:
return QString(tr("Connections"));
break;
case COLUMN_PEERNAME:
return QString(tr("Profile"));
break;
case COLUMN_I_AUTH_PEER:
return QString(tr("Trust level"));
break;
case COLUMN_PEER_AUTH_ME:
return QString(tr("Has signed your key?"));
break;
case COLUMN_PEERID:
return QString(tr("Id"));
break;
case COLUMN_LAST_USED:
return QString(tr("Last used"));
break;
}
}
else if (role == Qt::TextAlignmentRole)
{
switch(section)
{
default:
return (uint32_t)(Qt::AlignHCenter | Qt::AlignVCenter);
break;
}
}
else if(role == Qt::SizeHintRole)
{
switch(section)
{
case COLUMN_CHECK:
return 25*font_height;
break;
case COLUMN_PEERNAME: case COLUMN_I_AUTH_PEER: case COLUMN_PEER_AUTH_ME:
return 200*font_height;
break;
case COLUMN_LAST_USED:
return 75*font_height;
break;
}
}
}
return QVariant();
}
int pgpid_item_model::rowCount(const QModelIndex &/*parent*/) const
{
return neighs.size();
}
int pgpid_item_model::columnCount(const QModelIndex &/*parent*/) const
{
return COLUMN_COUNT;
}
QVariant pgpid_item_model::data(const QModelIndex &index, int role) const
{
if (!index.isValid())
return QVariant();
if((unsigned)index.row() >= neighs.size())
return QVariant();
//shit code (please rewrite it)
std::list<RsPgpId>::iterator it = neighs.begin();
for(int i = 0; i < index.row(); i++)
it++;
RsPeerDetails detail;
if (!rsPeers->getGPGDetails(*it, detail))
return QVariant();
//shit code end
if(role == Qt::EditRole) //some columns return raw data for editrole, used for proper filtering
{
switch(index.column())
{
case COLUMN_LAST_USED:
return detail.lastUsed;
break;
case COLUMN_I_AUTH_PEER:
{
if (detail.ownsign)
return RS_TRUST_LVL_ULTIMATE;
return detail.trustLvl;
}
break;
case COLUMN_PEER_AUTH_ME:
return detail.hasSignedMe;
break;
case COLUMN_CHECK:
return detail.accept_connection;
break;
default:
break;
}
}
//we using editrole only where it is useful, for other data we use display, so no "else if" here
if(role == Qt::DisplayRole || role == Qt::EditRole)
{
switch(index.column())
{
case COLUMN_PEERNAME:
return QString::fromUtf8(detail.name.c_str());
break;
case COLUMN_PEERID:
return QString::fromStdString(detail.gpg_id.toStdString());
break;
case COLUMN_I_AUTH_PEER:
{
if (detail.ownsign)
return tr("Personal signature");
else
{
switch(detail.trustLvl)
{
case RS_TRUST_LVL_MARGINAL: return tr("Marginally trusted peer") ; break;
case RS_TRUST_LVL_FULL:
case RS_TRUST_LVL_ULTIMATE: return tr("Fully trusted peer") ; break ;
case RS_TRUST_LVL_UNKNOWN:
case RS_TRUST_LVL_UNDEFINED:
case RS_TRUST_LVL_NEVER:
default: return tr("Untrusted peer") ; break ;
}
}
}
break;
case COLUMN_PEER_AUTH_ME:
{
if (detail.hasSignedMe)
return tr("Yes");
else
return tr("No");
}
break;
case COLUMN_LAST_USED:
{
time_t now = time(NULL);
uint64_t last_time_used = now - detail.lastUsed ;
QString lst_used_str ;
if(last_time_used < 3600)
lst_used_str = tr("Last hour") ;
else if(last_time_used < 86400)
lst_used_str = tr("Today") ;
else if(last_time_used > 86400 * 15000)
lst_used_str = tr("Never");
else
lst_used_str = tr("%1 days ago").arg((int)( last_time_used / 86400 )) ;
return lst_used_str;
}
break;
case COLUMN_CHECK:
{
if (detail.accept_connection)
{
return tr("Accepted");
}
else
{
return tr(" - ");
}
}
break;
}
}
else if(role == Qt::ToolTipRole)
{
switch(index.column())
{
case COLUMN_I_AUTH_PEER:
{
if (detail.ownsign)
return tr("PGP key signed by you");
}
break;
default:
{
if (!detail.accept_connection && detail.hasSignedMe)
{
return QString::fromUtf8(detail.name.c_str()) + tr(" has authenticated you. \nRight-click and select 'make friend' to be able to connect.");
}
}
break;
}
}
else if(role == Qt::DecorationRole)
{
switch(index.column())
{
case COLUMN_CHECK:
{
if (detail.accept_connection)
return QIcon(IMAGE_AUTHED);
else
return QIcon(IMAGE_DENIED);
}
break;
}
}
else if(role == Qt::BackgroundRole)
{
if (detail.accept_connection)
{
if (detail.ownsign)
{
return QBrush(mBackgroundColorOwnSign);
}
else
{
return QBrush(mBackgroundColorAcceptConnection);
}
}
else
{
if (detail.hasSignedMe)
{
return QBrush(mBackgroundColorHasSignedMe);
}
else
{
return QBrush(mBackgroundColorDenied);
}
}
}
return QVariant();
}
//following code is just a poc, it's still suboptimal, unefficient, but much better then existing rs code
void pgpid_item_model::data_updated(std::list<RsPgpId> &new_neighs)
{
//shit code follow (rewrite this please)
size_t old_size = neighs.size(), new_size = 0;
std::list<RsPgpId> old_neighs = neighs;
new_size = new_neighs.size();
//set model data to new cleaned up data
neighs = new_neighs;
neighs.sort();
neighs.unique(); //remove possible dups
//reflect actual row count in model
if(old_size < new_size)
{
beginInsertRows(QModelIndex(), old_size, new_size);
insertRows(old_size, new_size - old_size);
endInsertRows();
}
else if(new_size < old_size)
{
beginRemoveRows(QModelIndex(), new_size, old_size);
removeRows(old_size, old_size - new_size);
endRemoveRows();
}
//update data in ui, to avoid unnecessary redraw and ui updates, updating only changed elements
//TODO: libretroshare should implement a way to obtain only changed elements via some signalling non-blocking api.
{
size_t ii1 = 0;
for(auto i1 = neighs.begin(), end1 = neighs.end(), i2 = old_neighs.begin(), end2 = old_neighs.end(); i1 != end1; ++i1, ++i2, ii1++)
{
if(i2 == end2)
break;
if(*i1 != *i2)
{
QModelIndex topLeft = createIndex(ii1,0), bottomRight = createIndex(ii1, COLUMN_COUNT-1);
emit dataChanged(topLeft, bottomRight);
}
}
}
if(new_size > old_size)
{
QModelIndex topLeft = createIndex(old_size ? old_size -1 : 0 ,0), bottomRight = createIndex(new_size -1, COLUMN_COUNT-1);
emit dataChanged(topLeft, bottomRight);
}
//dirty solution for initial data fetch
//TODO: do it properly!
if(!old_size)
{
beginResetModel();
endResetModel();
}
//shit code end
}

View File

@ -0,0 +1,58 @@
#ifndef KEY_ITEM_MODEL_H
#define KEY_ITEM_MODEL_H
#include <QAbstractItemModel>
#include <retroshare/rspeers.h>
#include <QColor>
#define IMAGE_AUTHED ":/images/accepted16.png"
#define IMAGE_DENIED ":/images/denied16.png"
#define IMAGE_TRUSTED ":/images/rs-2.png"
#define COLUMN_CHECK 0
#define COLUMN_PEERNAME 1
#define COLUMN_I_AUTH_PEER 2
#define COLUMN_PEER_AUTH_ME 3
#define COLUMN_PEERID 4
#define COLUMN_LAST_USED 5
#define COLUMN_COUNT 6
class pgpid_item_model : public QAbstractTableModel
{
Q_OBJECT
public:
explicit pgpid_item_model(std::list<RsPgpId> &neighs, float &font_height, QObject *parent = nullptr);
// Header:
QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const ;
int rowCount(const QModelIndex &parent = QModelIndex()) const ;
int columnCount(const QModelIndex &parent = QModelIndex()) const ;
QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const ;
void setBackgroundColorSelf(QColor color) { mBackgroundColorSelf = color; }
void setBackgroundColorOwnSign(QColor color) { mBackgroundColorOwnSign = color; }
void setBackgroundColorAcceptConnection(QColor color) { mBackgroundColorAcceptConnection = color; }
void setBackgroundColorHasSignedMe(QColor color) { mBackgroundColorHasSignedMe = color; }
void setBackgroundColorDenied(QColor color) { mBackgroundColorDenied = color; }
public slots:
void data_updated(std::list<RsPgpId> &new_neighs);
private:
std::list<RsPgpId> &neighs;
float font_height;
QColor mBackgroundColorSelf;
QColor mBackgroundColorOwnSign;
QColor mBackgroundColorAcceptConnection;
QColor mBackgroundColorHasSignedMe;
QColor mBackgroundColorDenied;
};
#endif // KEY_ITEM_MODEL_H

View File

@ -0,0 +1,48 @@
#include "pgpid_item_proxy.h"
//TODO: include only required headers here
#include <retroshare/rsiface.h>
#include <retroshare/rspeers.h>
#include <retroshare/rsdisc.h>
#include <retroshare/rsmsgs.h>
//TODO: set this defines in one place
// Defines for key list columns
#define COLUMN_CHECK 0
#define COLUMN_PEERNAME 1
#define COLUMN_I_AUTH_PEER 2
#define COLUMN_PEER_AUTH_ME 3
#define COLUMN_PEERID 4
#define COLUMN_LAST_USED 5
#define COLUMN_COUNT 6
pgpid_item_proxy::pgpid_item_proxy(QObject *parent) :
QSortFilterProxyModel(parent)
{
}
void pgpid_item_proxy::use_only_trusted_keys(bool val)
{
only_trusted_keys = val;
filterChanged();
}
bool pgpid_item_proxy::filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const
{
if(only_trusted_keys)
{
if(!rsPeers)
return false;
RsPgpId peer_id (sourceModel()->data(sourceModel()->index(sourceRow, COLUMN_PEERID, sourceParent)).toString().toStdString());
RsPeerDetails details;
if(!rsPeers->getGPGDetails(peer_id, details))
return false;
if(details.validLvl < RS_TRUST_LVL_MARGINAL)
return false;
}
return QSortFilterProxyModel::filterAcceptsRow(sourceRow, sourceParent);
}

View File

@ -0,0 +1,21 @@
#ifndef PGPID_ITEM_PROXY_H
#define PGPID_ITEM_PROXY_H
#include <QSortFilterProxyModel>
class pgpid_item_proxy :
public QSortFilterProxyModel
{
Q_OBJECT
public:
pgpid_item_proxy(QObject *parent = nullptr);
bool filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const override;
public slots:
void use_only_trusted_keys(bool val);
private:
bool only_trusted_keys = false;
};
#endif // PGPID_ITEM_PROXY_H

View File

@ -1065,10 +1065,21 @@ void RetroshareDirModel::createCollectionFile(QWidget *parent, const QModelIndex
std::vector <DirDetails> dirVec; std::vector <DirDetails> dirVec;
getDirDetailsFromSelect(list, dirVec); getDirDetailsFromSelect(list, dirVec);
RsCollection(dirVec).openNewColl(parent); FileSearchFlags f = RemoteMode?RS_FILE_HINTS_REMOTE:RS_FILE_HINTS_LOCAL ;
QString dir_name;
if(!RemoteMode)
{
if(dirVec.size())
{
const DirDetails& details = dirVec[0];
dir_name = QDir(QString::fromUtf8(details.name.c_str())).dirName();
}
}
RsCollection(dirVec,f).openNewColl(parent,dir_name);
} }
void RetroshareDirModel::downloadSelected(const QModelIndexList &list) void RetroshareDirModel::downloadSelected(const QModelIndexList &list,bool interactive)
{ {
if (!RemoteMode) if (!RemoteMode)
{ {
@ -1085,8 +1096,11 @@ void RetroshareDirModel::downloadSelected(const QModelIndexList &list)
std::vector <DirDetails> dirVec; std::vector <DirDetails> dirVec;
getDirDetailsFromSelect(list, dirVec); getDirDetailsFromSelect(list, dirVec);
FileSearchFlags f = RemoteMode?RS_FILE_HINTS_REMOTE:RS_FILE_HINTS_LOCAL ;
/* Fire off requests */ if(interactive)
RsCollection(dirVec,f).downloadFiles() ;
else /* Fire off requests */
for (int i = 0, n = dirVec.size(); i < n; ++i) for (int i = 0, n = dirVec.size(); i < n; ++i)
{ {
if (!RemoteMode) if (!RemoteMode)

View File

@ -63,7 +63,7 @@ class RetroshareDirModel : public QAbstractItemModel
bool visible() { return _visible ;} bool visible() { return _visible ;}
/* Callback from GUI */ /* Callback from GUI */
void downloadSelected(const QModelIndexList &list); void downloadSelected(const QModelIndexList &list, bool interactive);
void createCollectionFile(QWidget *parent, const QModelIndexList &list); void createCollectionFile(QWidget *parent, const QModelIndexList &list);
void getDirDetailsFromSelect (const QModelIndexList &list, std::vector <DirDetails>& dirVec); void getDirDetailsFromSelect (const QModelIndexList &list, std::vector <DirDetails>& dirVec);

View File

@ -1220,6 +1220,11 @@ static void processList(const QStringList &list, const QString &textSingular, co
errorList << &fileExist << &personExist << &personFailed << &personNotFound << &forumUnknown << &forumMsgUnknown << &channelUnknown << &channelMsgUnknown << &postedUnknown << &postedMsgUnknown << &messageReceipientNotAccepted << &messageReceipientUnknown; errorList << &fileExist << &personExist << &personFailed << &personNotFound << &forumUnknown << &forumMsgUnknown << &channelUnknown << &channelMsgUnknown << &postedUnknown << &postedMsgUnknown << &messageReceipientNotAccepted << &messageReceipientUnknown;
// not needed: forumFound, channelFound, messageStarted // not needed: forumFound, channelFound, messageStarted
// we want to merge all single file links into one collection
// if a collection tree link is found it is processed independen for the other file links
RsCollection col;
bool fileLinkFound = false;
for (linkIt = links.begin(); linkIt != links.end(); ++linkIt) { for (linkIt = links.begin(); linkIt != links.end(); ++linkIt) {
const RetroShareLink &link = *linkIt; const RetroShareLink &link = *linkIt;
@ -1365,11 +1370,8 @@ static void processList(const QStringList &list, const QString &textSingular, co
break; break;
case TYPE_FILE: case TYPE_FILE:
{
RsCollection col ;
col.merge_in(link.name(),link.size(),RsFileHash(link.hash().toStdString())) ; col.merge_in(link.name(),link.size(),RsFileHash(link.hash().toStdString())) ;
col.downloadFiles(); fileLinkFound = true;
}
break; break;
@ -1557,6 +1559,10 @@ static void processList(const QStringList &list, const QString &textSingular, co
} }
} }
// were single file links found?
if (fileLinkFound)
col.downloadFiles();
int countProcessed = 0; int countProcessed = 0;
int countError = 0; int countError = 0;

View File

@ -63,7 +63,9 @@ const static uint32_t timeToInactivity = 60 * 10; // in seconds
/** Default constructor */ /** Default constructor */
ChatLobbyDialog::ChatLobbyDialog(const ChatLobbyId& lid, QWidget *parent, Qt::WindowFlags flags) ChatLobbyDialog::ChatLobbyDialog(const ChatLobbyId& lid, QWidget *parent, Qt::WindowFlags flags)
: ChatDialog(parent, flags), lobbyId(lid) : ChatDialog(parent, flags), lobbyId(lid),
bullet_red_128(":/icons/bullet_red_128.png"), bullet_grey_128(":/icons/bullet_grey_128.png"),
bullet_green_128(":/icons/bullet_green_128.png"), bullet_yellow_128(":/icons/bullet_yellow_128.png")
{ {
/* Invoke Qt Designer generated QObject setup routine */ /* Invoke Qt Designer generated QObject setup routine */
ui.setupUi(this); ui.setupUi(this);
@ -556,16 +558,16 @@ void ChatLobbyDialog::updateParticipantsList()
if(isParticipantMuted(it2->first)) if(isParticipantMuted(it2->first))
widgetitem->setIcon(COLUMN_ICON, QIcon(":/icons/bullet_red_128.png")); widgetitem->setIcon(COLUMN_ICON, bullet_red_128);
else if (tLastAct + timeToInactivity < now) else if (tLastAct + timeToInactivity < now)
widgetitem->setIcon(COLUMN_ICON, QIcon(":/icons/bullet_grey_128.png")); widgetitem->setIcon(COLUMN_ICON, bullet_grey_128);
else else
widgetitem->setIcon(COLUMN_ICON, QIcon(":/icons/bullet_green_128.png")); widgetitem->setIcon(COLUMN_ICON, bullet_green_128);
RsGxsId gxs_id; RsGxsId gxs_id;
rsMsgs->getIdentityForChatLobby(lobbyId, gxs_id); rsMsgs->getIdentityForChatLobby(lobbyId, gxs_id);
if (RsGxsId(participant.toStdString()) == gxs_id) widgetitem->setIcon(COLUMN_ICON, QIcon(":/icons/bullet_yellow_128.png")); if (RsGxsId(participant.toStdString()) == gxs_id) widgetitem->setIcon(COLUMN_ICON, bullet_yellow_128);
widgetitem->updateBannedState(); widgetitem->updateBannedState();

View File

@ -120,6 +120,8 @@ private:
QAction *showinpeopleAct; QAction *showinpeopleAct;
GxsIdChooser *ownIdChooser ; GxsIdChooser *ownIdChooser ;
//icons cache
QIcon bullet_red_128, bullet_grey_128, bullet_green_128, bullet_yellow_128;
}; };
#endif #endif

View File

@ -1589,10 +1589,9 @@ void ChatWidget::fileHashingFinished(QList<HashedFile> hashedFiles)
RetroShareLink link; RetroShareLink link;
if(mDefaultExtraFileFlags & RS_FILE_REQ_ANONYMOUS_ROUTING) // We dont use extra links anymore, since files in the extra list can always be accessed using anonymous+encrypted FT.
link = RetroShareLink::createFile(hashedFile.filename, hashedFile.size, QString::fromStdString(hashedFile.hash.toStdString())); link = RetroShareLink::createFile(hashedFile.filename, hashedFile.size, QString::fromStdString(hashedFile.hash.toStdString()));
else
link = RetroShareLink::createExtraFile(hashedFile.filename, hashedFile.size, QString::fromStdString(hashedFile.hash.toStdString()),QString::fromStdString(rsPeers->getOwnId().toStdString()));
if (hashedFile.flag & HashedFile::Picture) { if (hashedFile.flag & HashedFile::Picture) {
message += QString("<img src=\"file:///%1\" width=\"100\" height=\"100\">").arg(hashedFile.filepath); message += QString("<img src=\"file:///%1\" width=\"100\" height=\"100\">").arg(hashedFile.filepath);

View File

@ -56,14 +56,20 @@ RsCollection::RsCollection(const FileTree& fr)
recursAddElements(_xml_doc,fr,0,_root) ; recursAddElements(_xml_doc,fr,0,_root) ;
} }
RsCollection::RsCollection(const std::vector<DirDetails>& file_infos, QObject *parent) RsCollection::RsCollection(const std::vector<DirDetails>& file_infos,FileSearchFlags flags, QObject *parent)
: QObject(parent), _xml_doc("RsCollection") : QObject(parent), _xml_doc("RsCollection")
{ {
_root = _xml_doc.createElement("RsCollection"); _root = _xml_doc.createElement("RsCollection");
_xml_doc.appendChild(_root); _xml_doc.appendChild(_root);
if(! ( (flags & RS_FILE_HINTS_LOCAL) || (flags & RS_FILE_HINTS_REMOTE)))
{
std::cerr << "(EE) Wrong flags passed to RsCollection constructor. Please fix the code!" << std::endl;
return ;
}
for(uint32_t i = 0;i<file_infos.size();++i) for(uint32_t i = 0;i<file_infos.size();++i)
recursAddElements(_xml_doc,file_infos[i],_root) ; recursAddElements(_xml_doc,file_infos[i],_root,flags) ;
} }
RsCollection::~RsCollection() RsCollection::~RsCollection()
@ -170,7 +176,7 @@ void RsCollection::recursCollectColFileInfos(const QDomElement& e,std::vector<Co
} }
void RsCollection::recursAddElements(QDomDocument& doc,const DirDetails& details,QDomElement& e) const void RsCollection::recursAddElements(QDomDocument& doc,const DirDetails& details,QDomElement& e,FileSearchFlags flags) const
{ {
if (details.type == DIR_TYPE_FILE) if (details.type == DIR_TYPE_FILE)
{ {
@ -194,12 +200,11 @@ void RsCollection::recursAddElements(QDomDocument& doc,const DirDetails& details
continue; continue;
DirDetails subDirDetails; DirDetails subDirDetails;
FileSearchFlags flags = RS_FILE_HINTS_LOCAL;
if (!rsFiles->RequestDirDetails(details.children[i].ref, subDirDetails, flags)) if (!rsFiles->RequestDirDetails(details.children[i].ref, subDirDetails, flags))
continue; continue;
recursAddElements(doc,subDirDetails,d) ; recursAddElements(doc,subDirDetails,d,flags) ;
} }
e.appendChild(d) ; e.appendChild(d) ;
@ -408,9 +413,8 @@ bool RsCollection::save(QWidget *parent) const
} }
bool RsCollection::openNewColl(QWidget *parent) bool RsCollection::openNewColl(QWidget *parent, QString fileName)
{ {
QString fileName;
if(!misc::getSaveFileName(parent, RshareSettings::LASTDIR_EXTRAFILE if(!misc::getSaveFileName(parent, RshareSettings::LASTDIR_EXTRAFILE
, QApplication::translate("RsCollectionFile", "Create collection file") , QApplication::translate("RsCollectionFile", "Create collection file")
, QApplication::translate("RsCollectionFile", "Collection files") + " (*." + RsCollection::ExtensionString + ")" , QApplication::translate("RsCollectionFile", "Collection files") + " (*." + RsCollection::ExtensionString + ")"

View File

@ -64,7 +64,7 @@ public:
RsCollection(QObject *parent = 0) ; RsCollection(QObject *parent = 0) ;
// create from list of files and directories // create from list of files and directories
RsCollection(const std::vector<DirDetails>& file_entries, QObject *parent = 0) ; RsCollection(const std::vector<DirDetails>& file_entries, FileSearchFlags flags, QObject *parent = 0) ;
RsCollection(const FileTree& fr); RsCollection(const FileTree& fr);
virtual ~RsCollection() ; virtual ~RsCollection() ;
@ -82,7 +82,7 @@ public:
bool save(const QString& fileName) const ; bool save(const QString& fileName) const ;
// Open new collection // Open new collection
bool openNewColl(QWidget *parent); bool openNewColl(QWidget *parent, QString fileName = "");
// Open existing collection // Open existing collection
bool openColl(const QString& fileName, bool readOnly = false, bool showError = true); bool openColl(const QString& fileName, bool readOnly = false, bool showError = true);
@ -98,7 +98,7 @@ private slots:
private: private:
void recursAddElements(QDomDocument&,const DirDetails&,QDomElement&) const ; void recursAddElements(QDomDocument&, const DirDetails&, QDomElement&, FileSearchFlags flags) const ;
void recursAddElements(QDomDocument&,const ColFileInfo&,QDomElement&) const; void recursAddElements(QDomDocument&,const ColFileInfo&,QDomElement&) const;
void recursAddElements(QDomDocument& doc,const FileTree& ft,uint32_t index,QDomElement& e) const; void recursAddElements(QDomDocument& doc,const FileTree& ft,uint32_t index,QDomElement& e) const;

View File

@ -46,7 +46,7 @@
"emojione/people.png"|":neutral_face:":"emojione/1F610.png"; "emojione/people.png"|":neutral_face:":"emojione/1F610.png";
"emojione/people.png"|":expressionless:|-_-":"emojione/1F611.png"; "emojione/people.png"|":expressionless:|-_-":"emojione/1F611.png";
"emojione/people.png"|":hushed:":"emojione/1F62F.png"; "emojione/people.png"|":hushed:":"emojione/1F62F.png";
"emojione/people.png"|":frowning:":"emojione/1f626.png"; "emojione/people.png"|":frowning:":"emojione/1F626.png";
"emojione/people.png"|":anguished:":"emojione/1F627.png"; "emojione/people.png"|":anguished:":"emojione/1F627.png";
"emojione/people.png"|":open_mouth:|:-O|:O":"emojione/1F62E.png"; "emojione/people.png"|":open_mouth:|:-O|:O":"emojione/1F62E.png";
"emojione/people.png"|":astonished:":"emojione/1F632.png"; "emojione/people.png"|":astonished:":"emojione/1F632.png";
@ -82,7 +82,7 @@
"emojione/people.png"|":alien:":"emojione/1F47D.png"; "emojione/people.png"|":alien:":"emojione/1F47D.png";
"emojione/people.png"|":space_invader:":"emojione/1F47E.png"; "emojione/people.png"|":space_invader:":"emojione/1F47E.png";
"emojione/people.png"|":robot_face:":"emojione/1f916.png"; "emojione/people.png"|":robot_face:":"emojione/1f916.png";
"emojione/people.png"|":jack_o_lantern:":"emojione/1f383.png"; "emojione/people.png"|":jack_o_lantern:":"emojione/1F383.png";
"emojione/people.png"|":poop:|:shit:|:hankey:|:poo:":"emojione/1F4A9.png"; "emojione/people.png"|":poop:|:shit:|:hankey:|:poo:":"emojione/1F4A9.png";
"emojione/people.png"|":smile_cat:|(@)":"emojione/1F638.png"; "emojione/people.png"|":smile_cat:|(@)":"emojione/1F638.png";
"emojione/people.png"|":joy_cat:":"emojione/1F639.png"; "emojione/people.png"|":joy_cat:":"emojione/1F639.png";

View File

@ -13,7 +13,7 @@
<property name="windowTitle"> <property name="windowTitle">
<string>Form</string> <string>Form</string>
</property> </property>
<layout class="QVBoxLayout" name="verticalLayout_3"> <layout class="QVBoxLayout" name="GxsCommentDialogVLayout">
<item> <item>
<widget class="QFrame" name="postFrame"> <widget class="QFrame" name="postFrame">
<property name="sizePolicy"> <property name="sizePolicy">
@ -22,7 +22,7 @@
<verstretch>0</verstretch> <verstretch>0</verstretch>
</sizepolicy> </sizepolicy>
</property> </property>
<layout class="QVBoxLayout" name="verticalLayout"> <layout class="QVBoxLayout" name="postFrameVLayout">
<property name="leftMargin"> <property name="leftMargin">
<number>9</number> <number>9</number>
</property> </property>
@ -36,7 +36,7 @@
</widget> </widget>
</item> </item>
<item> <item>
<layout class="QHBoxLayout" name="horizontalLayout"> <layout class="QHBoxLayout" name="toolBarHLayout">
<item> <item>
<widget class="QPushButton" name="hotSortButton"> <widget class="QPushButton" name="hotSortButton">
<property name="text"> <property name="text">
@ -80,7 +80,7 @@
</widget> </widget>
</item> </item>
<item> <item>
<spacer name="horizontalSpacer"> <spacer name="toolBarHSpacer">
<property name="orientation"> <property name="orientation">
<enum>Qt::Horizontal</enum> <enum>Qt::Horizontal</enum>
</property> </property>
@ -93,7 +93,7 @@
</spacer> </spacer>
</item> </item>
<item> <item>
<widget class="QLabel" name="label_2"> <widget class="QLabel" name="idLabel">
<property name="text"> <property name="text">
<string>Voter ID:</string> <string>Voter ID:</string>
</property> </property>

View File

@ -21,13 +21,14 @@
* *
*/ */
#include <QMimeData>
#include <QTextDocument>
#include <QAbstractTextDocumentLayout> #include <QAbstractTextDocumentLayout>
#include <QApplication> #include <QApplication>
#include <QClipboard>
#include <QDateTime> #include <QDateTime>
#include <QMenu> #include <QMenu>
#include <QMimeData>
#include <QPainter> #include <QPainter>
#include <QTextDocument>
#include "gui/common/RSElidedItemDelegate.h" #include "gui/common/RSElidedItemDelegate.h"
#include "gui/gxs/GxsCommentTreeWidget.h" #include "gui/gxs/GxsCommentTreeWidget.h"
@ -55,6 +56,7 @@
/* Images for context menu icons */ /* Images for context menu icons */
#define IMAGE_MESSAGE ":/images/folder-draft.png" #define IMAGE_MESSAGE ":/images/folder-draft.png"
#define IMAGE_COPY ":/images/copy.png"
#define IMAGE_VOTEUP ":/images/vote_up.png" #define IMAGE_VOTEUP ":/images/vote_up.png"
#define IMAGE_VOTEDOWN ":/images/vote_down.png" #define IMAGE_VOTEDOWN ":/images/vote_down.png"
@ -170,6 +172,7 @@ void GxsCommentTreeWidget::setCurrentCommentMsgId(QTreeWidgetItem *current, QTre
if(current) if(current)
{ {
mCurrentCommentMsgId = RsGxsMessageId(current->text(PCITEM_COLUMN_MSGID).toStdString()); mCurrentCommentMsgId = RsGxsMessageId(current->text(PCITEM_COLUMN_MSGID).toStdString());
mCurrentCommentText = current->text(PCITEM_COLUMN_COMMENT);
} }
} }
@ -180,6 +183,8 @@ void GxsCommentTreeWidget::customPopUpMenu(const QPoint& /*point*/)
action->setDisabled(mCurrentCommentMsgId.isNull()); action->setDisabled(mCurrentCommentMsgId.isNull());
action = contextMnu.addAction(QIcon(IMAGE_MESSAGE), tr("Submit Comment"), this, SLOT(makeComment())); action = contextMnu.addAction(QIcon(IMAGE_MESSAGE), tr("Submit Comment"), this, SLOT(makeComment()));
action->setDisabled(mMsgVersions.empty()); action->setDisabled(mMsgVersions.empty());
action = contextMnu.addAction(QIcon(IMAGE_COPY), tr("Copy Comment"), this, SLOT(copyComment()));
action->setDisabled(mCurrentCommentMsgId.isNull());
contextMnu.addSeparator(); contextMnu.addSeparator();
@ -308,6 +313,14 @@ void GxsCommentTreeWidget::replyToComment()
pcc.exec(); pcc.exec();
} }
void GxsCommentTreeWidget::copyComment()
{
QMimeData *mimeData = new QMimeData();
mimeData->setHtml("<html>"+mCurrentCommentText+"</html>");
QClipboard *clipboard = QApplication::clipboard();
clipboard->setMimeData(mimeData, QClipboard::Clipboard);
}
void GxsCommentTreeWidget::setup(RsTokenService *token_service, RsGxsCommentService *comment_service) void GxsCommentTreeWidget::setup(RsTokenService *token_service, RsGxsCommentService *comment_service)
{ {
mRsTokenService = token_service; mRsTokenService = token_service;

View File

@ -71,6 +71,8 @@ public slots:
void makeComment(); void makeComment();
void replyToComment(); void replyToComment();
void copyComment();
void voteUp(); void voteUp();
void voteDown(); void voteDown();
@ -89,6 +91,7 @@ protected:
std::set<RsGxsMessageId> mMsgVersions; std::set<RsGxsMessageId> mMsgVersions;
RsGxsMessageId mLatestMsgId; RsGxsMessageId mLatestMsgId;
RsGxsMessageId mCurrentCommentMsgId; RsGxsMessageId mCurrentCommentMsgId;
QString mCurrentCommentText;
RsGxsId mVoterId; RsGxsId mVoterId;
std::map<RsGxsMessageId, QTreeWidgetItem *> mLoadingMap; std::map<RsGxsMessageId, QTreeWidgetItem *> mLoadingMap;

View File

@ -630,7 +630,7 @@ void CreateGxsChannelMsg::sendMsg()
std::string subject = std::string(misc::removeNewLine(subjectEdit->text()).toUtf8()); std::string subject = std::string(misc::removeNewLine(subjectEdit->text()).toUtf8());
QString text; QString text;
RsHtml::optimizeHtml(msgEdit, text); RsHtml::optimizeHtml(msgEdit, text);
std::string msg = text.toStdString(); std::string msg = std::string(text.toUtf8());
std::list<RsGxsFile> files; std::list<RsGxsFile> files;

View File

@ -122,7 +122,7 @@ MessageWidget *MessageWidget::openMsg(const std::string &msgId, bool window)
/** Constructor */ /** Constructor */
MessageWidget::MessageWidget(bool controlled, QWidget *parent, Qt::WindowFlags flags) MessageWidget::MessageWidget(bool controlled, QWidget *parent, Qt::WindowFlags flags)
: QWidget(parent, flags) : QWidget(parent, flags), toolButtonReply(NULL)
{ {
/* Invoke the Qt Designer generated object setup routine */ /* Invoke the Qt Designer generated object setup routine */
ui.setupUi(this); ui.setupUi(this);
@ -196,6 +196,7 @@ void MessageWidget::connectAction(enumActionType actionType, QToolButton* button
break; break;
case ACTION_REPLY: case ACTION_REPLY:
connect(button, SIGNAL(clicked()), this, SLOT(reply())); connect(button, SIGNAL(clicked()), this, SLOT(reply()));
toolButtonReply = button;
break; break;
case ACTION_REPLY_ALL: case ACTION_REPLY_ALL:
connect(button, SIGNAL(clicked()), this, SLOT(replyAll())); connect(button, SIGNAL(clicked()), this, SLOT(replyAll()));
@ -600,9 +601,11 @@ void MessageWidget::fill(const std::string &msgId)
if ((msgInfo.msgflags & RS_MSG_SYSTEM) && msgInfo.rspeerid_srcId == ownId) { if ((msgInfo.msgflags & RS_MSG_SYSTEM) && msgInfo.rspeerid_srcId == ownId) {
ui.fromText->setText("RetroShare"); ui.fromText->setText("RetroShare");
if (toolButtonReply) toolButtonReply->setEnabled(false);
} else { } else {
ui.fromText->setText(link.toHtml()); ui.fromText->setText(link.toHtml());
ui.fromText->setToolTip(tooltip_string) ; ui.fromText->setToolTip(tooltip_string) ;
if (toolButtonReply) toolButtonReply->setEnabled(true);
} }
ui.subjectText->setText(QString::fromUtf8(msgInfo.title.c_str())); ui.subjectText->setText(QString::fromUtf8(msgInfo.title.c_str()));

View File

@ -95,6 +95,8 @@ private:
QList<QLabel*> tagLabels; QList<QLabel*> tagLabels;
QToolButton* toolButtonReply;
/** Qt Designer generated object */ /** Qt Designer generated object */
Ui::MessageWidget ui; Ui::MessageWidget ui;
}; };

View File

@ -209,6 +209,12 @@
</item> </item>
<item row="3" column="2" colspan="2"> <item row="3" column="2" colspan="2">
<widget class="RSTextBrowser" name="ccText"> <widget class="RSTextBrowser" name="ccText">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Maximum">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="maximumSize"> <property name="maximumSize">
<size> <size>
<width>16777215</width> <width>16777215</width>
@ -238,6 +244,12 @@
</item> </item>
<item row="4" column="2" colspan="2"> <item row="4" column="2" colspan="2">
<widget class="RSTextBrowser" name="bccText"> <widget class="RSTextBrowser" name="bccText">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Maximum">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="maximumSize"> <property name="maximumSize">
<size> <size>
<width>16777215</width> <width>16777215</width>

View File

@ -68,7 +68,7 @@ MessageWindow::MessageWindow(QWidget *parent, Qt::WindowFlags flags)
QMenu *printmenu = new QMenu(); QMenu *printmenu = new QMenu();
printmenu->addAction(ui.actionPrint); printmenu->addAction(ui.actionPrint);
printmenu->addAction(ui.actionPrint_Preview); printmenu->addAction(ui.actionPrint_Preview);
ui.printbutton->setMenu(printmenu); ui.printButton->setMenu(printmenu);
// create view menu // create view menu
QMenu *viewmenu = new QMenu(); QMenu *viewmenu = new QMenu();
@ -120,7 +120,7 @@ void MessageWindow::addWidget(MessageWidget *widget)
msgWidget->connectAction(MessageWidget::ACTION_REPLY, ui.replymessageButton); msgWidget->connectAction(MessageWidget::ACTION_REPLY, ui.replymessageButton);
msgWidget->connectAction(MessageWidget::ACTION_REPLY_ALL, ui.replyallmessageButton); msgWidget->connectAction(MessageWidget::ACTION_REPLY_ALL, ui.replyallmessageButton);
msgWidget->connectAction(MessageWidget::ACTION_FORWARD, ui.forwardmessageButton); msgWidget->connectAction(MessageWidget::ACTION_FORWARD, ui.forwardmessageButton);
msgWidget->connectAction(MessageWidget::ACTION_PRINT, ui.printbutton); msgWidget->connectAction(MessageWidget::ACTION_PRINT, ui.printButton);
msgWidget->connectAction(MessageWidget::ACTION_PRINT, ui.actionPrint); msgWidget->connectAction(MessageWidget::ACTION_PRINT, ui.actionPrint);
msgWidget->connectAction(MessageWidget::ACTION_PRINT, actionPrint); msgWidget->connectAction(MessageWidget::ACTION_PRINT, actionPrint);
msgWidget->connectAction(MessageWidget::ACTION_PRINT_PREVIEW, ui.actionPrint_Preview); msgWidget->connectAction(MessageWidget::ACTION_PRINT_PREVIEW, ui.actionPrint_Preview);
@ -216,7 +216,7 @@ void MessageWindow::setToolbarButtonStyle(Qt::ToolButtonStyle style)
ui.replyallmessageButton->setToolButtonStyle(style); ui.replyallmessageButton->setToolButtonStyle(style);
ui.forwardmessageButton->setToolButtonStyle(style); ui.forwardmessageButton->setToolButtonStyle(style);
ui.tagButton->setToolButtonStyle(style); ui.tagButton->setToolButtonStyle(style);
ui.printbutton->setToolButtonStyle(style); ui.printButton->setToolButtonStyle(style);
ui.viewtoolButton->setToolButtonStyle(style); ui.viewtoolButton->setToolButtonStyle(style);
} }

View File

@ -11,11 +11,20 @@
</rect> </rect>
</property> </property>
<widget class="QWidget" name="centralwidget"> <widget class="QWidget" name="centralwidget">
<layout class="QGridLayout" name="gridLayout"> <layout class="QGridLayout" name="centralwidgetGLayout">
<property name="verticalSpacing"> <property name="leftMargin">
<number>0</number> <number>0</number>
</property> </property>
<property name="margin"> <property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<property name="verticalSpacing">
<number>0</number> <number>0</number>
</property> </property>
<item row="0" column="0"> <item row="0" column="0">
@ -44,8 +53,17 @@
<property name="frameShadow"> <property name="frameShadow">
<enum>QFrame::Sunken</enum> <enum>QFrame::Sunken</enum>
</property> </property>
<layout class="QGridLayout" name="gridLayout_3"> <layout class="QGridLayout" name="toolBarFrameGLayout">
<property name="margin"> <property name="leftMargin">
<number>2</number>
</property>
<property name="topMargin">
<number>2</number>
</property>
<property name="rightMargin">
<number>2</number>
</property>
<property name="bottomMargin">
<number>2</number> <number>2</number>
</property> </property>
<property name="horizontalSpacing"> <property name="horizontalSpacing">
@ -81,7 +99,7 @@
</widget> </widget>
</item> </item>
<item row="0" column="1"> <item row="0" column="1">
<widget class="Line" name="line"> <widget class="Line" name="toolBarFrameLineL">
<property name="orientation"> <property name="orientation">
<enum>Qt::Vertical</enum> <enum>Qt::Vertical</enum>
</property> </property>
@ -187,7 +205,7 @@
</widget> </widget>
</item> </item>
<item row="0" column="5"> <item row="0" column="5">
<widget class="Line" name="line_2"> <widget class="Line" name="toolBarFrameLineR">
<property name="orientation"> <property name="orientation">
<enum>Qt::Vertical</enum> <enum>Qt::Vertical</enum>
</property> </property>
@ -223,7 +241,7 @@
</widget> </widget>
</item> </item>
<item row="0" column="8"> <item row="0" column="8">
<widget class="QToolButton" name="printbutton"> <widget class="QToolButton" name="printButton">
<property name="focusPolicy"> <property name="focusPolicy">
<enum>Qt::NoFocus</enum> <enum>Qt::NoFocus</enum>
</property> </property>
@ -281,7 +299,7 @@
</widget> </widget>
</item> </item>
<item row="0" column="10"> <item row="0" column="10">
<spacer name="horizontalSpacer"> <spacer name="toolBarFrameHSpacer">
<property name="orientation"> <property name="orientation">
<enum>Qt::Horizontal</enum> <enum>Qt::Horizontal</enum>
</property> </property>

View File

@ -191,10 +191,11 @@ ServerPage::ServerPage(QWidget * parent, Qt::WindowFlags flags)
connect(ui.extAddress, SIGNAL(textChanged(QString)),this,SLOT(saveAddresses())); connect(ui.extAddress, SIGNAL(textChanged(QString)),this,SLOT(saveAddresses()));
connect(ui.dynDNS, SIGNAL(textChanged(QString)),this,SLOT(saveAddresses())); connect(ui.dynDNS, SIGNAL(textChanged(QString)),this,SLOT(saveAddresses()));
connect(ui.hiddenpage_proxyAddress_tor, SIGNAL(textChanged(QString)),this,SLOT(saveAddresses())); connect(ui.tabWidget, SIGNAL(currentChanged(int)), this, SLOT(tabChanged(int)));
connect(ui.hiddenpage_proxyPort_tor, SIGNAL(valueChanged(int)),this,SLOT(saveAddresses())); connect(ui.hiddenpage_proxyAddress_tor, SIGNAL(editingFinished()),this,SLOT(saveAddresses()));
connect(ui.hiddenpage_proxyAddress_i2p, SIGNAL(textChanged(QString)),this,SLOT(saveAddresses())); connect(ui.hiddenpage_proxyPort_tor, SIGNAL(editingFinished()),this,SLOT(saveAddresses()));
connect(ui.hiddenpage_proxyPort_i2p, SIGNAL(valueChanged(int)),this,SLOT(saveAddresses())); connect(ui.hiddenpage_proxyAddress_i2p, SIGNAL(editingFinished()),this,SLOT(saveAddresses()));
connect(ui.hiddenpage_proxyPort_i2p, SIGNAL(editingFinished()),this,SLOT(saveAddresses()));
connect(ui.totalDownloadRate,SIGNAL(valueChanged(int)),this,SLOT(saveRates())); connect(ui.totalDownloadRate,SIGNAL(valueChanged(int)),this,SLOT(saveRates()));
connect(ui.totalUploadRate, SIGNAL(valueChanged(int)),this,SLOT(saveRates())); connect(ui.totalUploadRate, SIGNAL(valueChanged(int)),this,SLOT(saveRates()));
@ -422,7 +423,6 @@ void ServerPage::load()
whileBlocking(ui.hiddenpage_proxyAddress_i2p) -> setText(QString::fromStdString(proxyaddr)); whileBlocking(ui.hiddenpage_proxyAddress_i2p) -> setText(QString::fromStdString(proxyaddr));
whileBlocking(ui.hiddenpage_proxyPort_i2p) -> setValue(proxyport); whileBlocking(ui.hiddenpage_proxyPort_i2p) -> setValue(proxyport);
updateOutProxyIndicator();
} }
//Relay Tab //Relay Tab
@ -873,8 +873,6 @@ void ServerPage::updateStatus()
else else
ui.iconlabel_ext->setPixmap(QPixmap(":/images/ledoff1.png")); ui.iconlabel_ext->setPixmap(QPixmap(":/images/ledoff1.png"));
// check for Tor
updateOutProxyIndicator();
} }
void ServerPage::toggleUPnP() void ServerPage::toggleUPnP()
@ -910,6 +908,9 @@ void ServerPage::saveAddresses()
saveCommon(); saveCommon();
if(ui.tabWidget->currentIndex() == 2) // hidden services tab
updateOutProxyIndicator();
if (mIsHiddenNode) { if (mIsHiddenNode) {
saveAddressesHiddenNode(); saveAddressesHiddenNode();
return; return;
@ -991,6 +992,12 @@ void ServerPage::saveRates()
rsConfig->SetMaxDataRates( ui.totalDownloadRate->value(), ui.totalUploadRate->value() ); rsConfig->SetMaxDataRates( ui.totalDownloadRate->value(), ui.totalUploadRate->value() );
} }
void ServerPage::tabChanged(int page)
{
if(page == 2)
updateOutProxyIndicator();
}
/***********************************************************************************/ /***********************************************************************************/
/***********************************************************************************/ /***********************************************************************************/
/******* ALTERNATIVE VERSION IF HIDDEN NODE ***************************************/ /******* ALTERNATIVE VERSION IF HIDDEN NODE ***************************************/
@ -1131,8 +1138,6 @@ void ServerPage::loadHiddenNode()
whileBlocking(ui.hiddenpage_proxyAddress_i2p) -> setText(QString::fromStdString(proxyaddr)); whileBlocking(ui.hiddenpage_proxyAddress_i2p) -> setText(QString::fromStdString(proxyaddr));
whileBlocking(ui.hiddenpage_proxyPort_i2p) -> setValue(proxyport); whileBlocking(ui.hiddenpage_proxyPort_i2p) -> setValue(proxyport);
updateOutProxyIndicator();
QString expected = ""; QString expected = "";
switch (mHiddenType) { switch (mHiddenType) {
case RS_HIDDEN_TYPE_I2P: case RS_HIDDEN_TYPE_I2P:
@ -1220,8 +1225,6 @@ void ServerPage::updateStatusHiddenNode()
ui.iconlabel_ext->setPixmap(QPixmap(":/images/ledoff1.png")); ui.iconlabel_ext->setPixmap(QPixmap(":/images/ledoff1.png"));
#endif #endif
updateOutProxyIndicator();
} }
void ServerPage::saveAddressesHiddenNode() void ServerPage::saveAddressesHiddenNode()
@ -1554,8 +1557,6 @@ void ServerPage::loadCommon()
whileBlocking(ui.hiddenpage_proxyPort_i2p) -> setValue(proxyport); whileBlocking(ui.hiddenpage_proxyPort_i2p) -> setValue(proxyport);
whileBlocking(ui.hiddenpage_proxyPort_i2p_2)->setValue(proxyport); // this one is for bob tab whileBlocking(ui.hiddenpage_proxyPort_i2p_2)->setValue(proxyport); // this one is for bob tab
updateOutProxyIndicator();
// don't use whileBlocking here // don't use whileBlocking here
ui.cb_enableBob->setChecked(mBobSettings.enableBob); ui.cb_enableBob->setChecked(mBobSettings.enableBob);

View File

@ -84,6 +84,7 @@ private slots:
void ipWhiteListContextMenu(const QPoint &point); void ipWhiteListContextMenu(const QPoint &point);
void removeBannedIp(); void removeBannedIp();
void tabChanged(int page);
// server // server
void saveAddresses(); void saveAddresses();
void saveRates(); void saveRates();

View File

@ -5,6 +5,7 @@
#include "TurtleRouterDialog.h" #include "TurtleRouterDialog.h"
#include <QPainter> #include <QPainter>
#include <QStylePainter> #include <QStylePainter>
#include <algorithm> // for sort
#include "gui/settings/rsharesettings.h" #include "gui/settings/rsharesettings.h"
@ -70,6 +71,10 @@ void TurtleRouterDialog::processSettings(bool bLoad)
} }
bool sr_Compare( TurtleRequestDisplayInfo m1, TurtleRequestDisplayInfo m2)
{
return m1.age < m2.age;
}
void TurtleRouterDialog::updateDisplay() void TurtleRouterDialog::updateDisplay()
{ {
@ -80,6 +85,8 @@ void TurtleRouterDialog::updateDisplay()
rsTurtle->getInfo(hashes_info,tunnels_info,search_reqs_info,tunnel_reqs_info) ; rsTurtle->getInfo(hashes_info,tunnels_info,search_reqs_info,tunnel_reqs_info) ;
std::sort(search_reqs_info.begin(),search_reqs_info.end(),sr_Compare) ;
updateTunnelRequests(hashes_info,tunnels_info,search_reqs_info,tunnel_reqs_info) ; updateTunnelRequests(hashes_info,tunnels_info,search_reqs_info,tunnel_reqs_info) ;
} }
@ -162,7 +169,7 @@ void TurtleRouterDialog::updateTunnelRequests( const std::vector<std::vector<std
for(uint i=0;i<search_reqs_info.size();++i) for(uint i=0;i<search_reqs_info.size();++i)
{ {
QString str = tr("Request id: %1\t from [%2]\t %3 secs ago").arg(search_reqs_info[i].request_id,0,16).arg(getPeerName(search_reqs_info[i].source_peer_id)).arg(search_reqs_info[i].age); QString str = tr("Request id: %1\t %3 secs ago\t from %2\t %4").arg(search_reqs_info[i].request_id,0,16).arg(getPeerName(search_reqs_info[i].source_peer_id), -25).arg(search_reqs_info[i].age).arg(QString::fromUtf8(search_reqs_info[i].keywords.c_str(),search_reqs_info[i].keywords.length()));
stl.clear() ; stl.clear() ;
stl.push_back(str) ; stl.push_back(str) ;

View File

@ -491,7 +491,7 @@ feenableexcept(FE_INVALID | FE_DIVBYZERO);
QObject::connect(notify,SIGNAL(chatStatusChanged(const QString&,const QString&,bool)),w->friendsDialog,SLOT(updatePeerStatusString(const QString&,const QString&,bool))); QObject::connect(notify,SIGNAL(chatStatusChanged(const QString&,const QString&,bool)),w->friendsDialog,SLOT(updatePeerStatusString(const QString&,const QString&,bool)));
QObject::connect(notify,SIGNAL(ownStatusMessageChanged()),w->friendsDialog,SLOT(loadmypersonalstatus())); QObject::connect(notify,SIGNAL(ownStatusMessageChanged()),w->friendsDialog,SLOT(loadmypersonalstatus()));
QObject::connect(notify,SIGNAL(logInfoChanged(const QString&)) ,w->friendsDialog->networkDialog,SLOT(setLogInfo(QString))) ; // QObject::connect(notify,SIGNAL(logInfoChanged(const QString&)) ,w->friendsDialog->networkDialog,SLOT(setLogInfo(QString))) ;
QObject::connect(notify,SIGNAL(discInfoChanged()) ,w->friendsDialog->networkView,SLOT(update()),Qt::QueuedConnection) ; QObject::connect(notify,SIGNAL(discInfoChanged()) ,w->friendsDialog->networkView,SLOT(update()),Qt::QueuedConnection) ;
QObject::connect(notify,SIGNAL(errorOccurred(int,int,const QString&)),w,SLOT(displayErrorMessage(int,int,const QString&))) ; QObject::connect(notify,SIGNAL(errorOccurred(int,int,const QString&)),w,SLOT(displayErrorMessage(int,int,const QString&))) ;

View File

@ -44,7 +44,7 @@ QFrame#titleBarFrame, QFrame#toolBarFrame
QToolTip QToolTip
{ {
border: 1px solid #3A3939; border: 1px solid #3A3939;
background-color: rgb(90, 102, 117);; background-color: rgb(90, 102, 117);
color: white; color: white;
padding: 1px; padding: 1px;
opacity: 200; opacity: 200;
@ -76,11 +76,11 @@ QWidget:item:selected
ForumsDialog, GxsForumThreadWidget ForumsDialog, GxsForumThreadWidget
{ {
qproperty-textColorRead: gray; qproperty-textColorRead: darkgray;
qproperty-textColorUnread: white; qproperty-textColorUnread: white;
qproperty-textColorUnreadChildren: gray; qproperty-textColorUnreadChildren: red;
qproperty-textColorNotSubscribed: white; qproperty-textColorNotSubscribed: white;
qproperty-textColorMissing: red; qproperty-textColorMissing: darkred;
} }
QMenuBar QMenuBar
@ -330,7 +330,7 @@ QTextEdit
QPlainTextEdit QPlainTextEdit
{ {
background-color: #201F1F;; background-color: #201F1F;
color: silver; color: silver;
border-radius: 3px; border-radius: 3px;
border: 1px solid #3A3939; border: 1px solid #3A3939;
@ -830,6 +830,14 @@ QTreeView, QListView
background-color: #201F1F; background-color: #201F1F;
} }
QTreeView::item {
background-color: #201F1F;
}
QTreeView::item:!selected {
color: #C0C0C0;
}
QTreeView:branch:selected, QTreeView:branch:hover QTreeView:branch:selected, QTreeView:branch:hover
{ {
background: url(qdarkstyle/transparent.png); background: url(qdarkstyle/transparent.png);
@ -867,14 +875,14 @@ QTreeView::branch:open:has-children:has-siblings:hover {
image: url(qdarkstyle/branch_open-on.png); image: url(qdarkstyle/branch_open-on.png);
} }
QListView::item:!selected:hover, QListView::item:!selected:hover, QTreeView::item:!selected:hover { QListView::item:!selected:hover, QTableView::item:!selected:hover, QTreeView::item:!selected:hover {
background: rgba(0, 0, 0, 0); background: rgba(0, 0, 0, 0);
outline: 0; outline: 0;
color: #FFFFFF color: #FFFFFF;
} }
QListView::item:selected:hover, QListView::item:selected:hover, QTreeView::item:selected:hover { QListView::item:selected:hover, QTableView::item:selected:hover, QTreeView::item:selected:hover {
background: #78879b;; background: #78879b;
color: #FFFFFF; color: #FFFFFF;
} }

View File

@ -614,8 +614,9 @@ HEADERS += rshare.h \
gui/statistics/BWGraph.h \ gui/statistics/BWGraph.h \
util/RsSyntaxHighlighter.h \ util/RsSyntaxHighlighter.h \
util/imageutil.h \ util/imageutil.h \
gui/NetworkDialog/pgpid_item_model.h \
gui/NetworkDialog/pgpid_item_proxy.h \
gui/common/RsCollection.h gui/common/RsCollection.h
# gui/ForumsDialog.h \ # gui/ForumsDialog.h \
# gui/forums/ForumDetails.h \ # gui/forums/ForumDetails.h \
# gui/forums/EditForumDetails.h \ # gui/forums/EditForumDetails.h \
@ -974,8 +975,9 @@ SOURCES += main.cpp \
gui/statistics/BWGraph.cpp \ gui/statistics/BWGraph.cpp \
util/RsSyntaxHighlighter.cpp \ util/RsSyntaxHighlighter.cpp \
util/imageutil.cpp \ util/imageutil.cpp \
gui/NetworkDialog/pgpid_item_model.cpp \
gui/NetworkDialog/pgpid_item_proxy.cpp \
gui/common/RsCollection.cpp gui/common/RsCollection.cpp
# gui/ForumsDialog.cpp \ # gui/ForumsDialog.cpp \
# gui/forums/ForumDetails.cpp \ # gui/forums/ForumDetails.cpp \
# gui/forums/EditForumDetails.cpp \ # gui/forums/EditForumDetails.cpp \

View File

@ -363,7 +363,7 @@ bool misc::getSaveFileName(QWidget *parent, RshareSettings::enumLastDir type
, QString &file, QString *selectedFilter , QString &file, QString *selectedFilter
, QFileDialog::Options options) , QFileDialog::Options options)
{ {
QString lastDir = Settings->getLastDir(type); QString lastDir = Settings->getLastDir(type) + "/" + file;
file = QFileDialog::getSaveFileName(parent, caption, lastDir, filter, selectedFilter, QFileDialog::DontUseNativeDialog | options); file = QFileDialog::getSaveFileName(parent, caption, lastDir, filter, selectedFilter, QFileDialog::DontUseNativeDialog | options);

View File

@ -93,7 +93,7 @@ CONFIG *= no_rs_async_chat
rs_async_chat:CONFIG -= no_rs_async_chat rs_async_chat:CONFIG -= no_rs_async_chat
# To select your MacOsX version append the following assignation to qmake # To select your MacOsX version append the following assignation to qmake
# command line "CONFIG+=rs_macos10.11" where 10.11(default for Travis_CI) depends your version # command line "CONFIG+=rs_macos10.11" where 10.11 depends your version
CONFIG *= rs_macos10.11 CONFIG *= rs_macos10.11
rs_macos10.8:CONFIG -= rs_macos10.11 rs_macos10.8:CONFIG -= rs_macos10.11
rs_macos10.9:CONFIG -= rs_macos10.11 rs_macos10.9:CONFIG -= rs_macos10.11
@ -174,6 +174,7 @@ win32 {
} }
} }
macx {
rs_macos10.8 { rs_macos10.8 {
message(***retroshare.pri: Set Target and SDK to MacOS 10.8 ) message(***retroshare.pri: Set Target and SDK to MacOS 10.8 )
QMAKE_MACOSX_DEPLOYMENT_TARGET=10.8 QMAKE_MACOSX_DEPLOYMENT_TARGET=10.8
@ -202,9 +203,10 @@ rs_macos10.12 {
message(***retroshare.pri: Set Target and SDK to MacOS 10.12 ) message(***retroshare.pri: Set Target and SDK to MacOS 10.12 )
QMAKE_MACOSX_DEPLOYMENT_TARGET=10.12 QMAKE_MACOSX_DEPLOYMENT_TARGET=10.12
QMAKE_MAC_SDK = macosx10.12 QMAKE_MAC_SDK = macosx10.12
QMAKE_CXXFLAGS += -Wno-nullability-completeness
QMAKE_CFLAGS += -Wno-nullability-completeness
} }
macx {
message(***retroshare.pri:MacOSX) message(***retroshare.pri:MacOSX)
BIN_DIR += "/usr/bin" BIN_DIR += "/usr/bin"
INC_DIR += "/usr/include" INC_DIR += "/usr/include"
@ -272,3 +274,44 @@ rs_async_chat {
rs_chatserver { rs_chatserver {
DEFINES *= RS_CHATSERVER DEFINES *= RS_CHATSERVER
} }
###########################################################################################################################################################
#
# V07_NON_BACKWARD_COMPATIBLE_CHANGE_001:
#
# 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: connexions impossible with non patched peers older than Nov 2017, 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).
#
# V07_NON_BACKWARD_COMPATIBLE_CHANGE_002:
#
# What: Use RSA+SHA256 instead of RSA+SHA1 for PGP certificate signatures
#
# Why: Sha1 is likely to be prone to primary collisions anytime soon, so it is urgent to turn to a more secure solution.
#
# Backward compat: unpatched peers after Nov 2017 are able to verify signatures since openpgp-sdk already handle it.
#
# V07_NON_BACKWARD_COMPATIBLE_CHANGE_003:
#
# What: Do not hash PGP certificate twice when signing
#
# Why: hasing twice is not per se a security issue, but it makes it harder to change the settings for hashing.
#
# Backward compat: patched peers cannot connect to non patched peers older than Nov 2017.
###########################################################################################################################################################
#CONFIG += rs_v07_changes
rs_v07_changes {
DEFINES += V07_NON_BACKWARD_COMPATIBLE_CHANGE_001
DEFINES += V07_NON_BACKWARD_COMPATIBLE_CHANGE_002
DEFINES += V07_NON_BACKWARD_COMPATIBLE_CHANGE_003
}