Removed stuff which hasn't been used anymore
This commit is contained in:
		
							parent
							
								
									14bfda467f
								
							
						
					
					
						commit
						bf689eca59
					
				@ -1,12 +1,11 @@
 | 
				
			|||||||
cmake_minimum_required(VERSION 3.6)
 | 
					cmake_minimum_required(VERSION 3.6)
 | 
				
			||||||
project(TeaSpeak-Parent)
 | 
					project(TeaSpeak-Parent)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
set(CMAKE_CXX_STANDARD 17)
 | 
					set(CMAKE_CXX_STANDARD 20)
 | 
				
			||||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++17")
 | 
					 | 
				
			||||||
set(CMAKE_INCLUDE_CURRENT_DIR ON)
 | 
					set(CMAKE_INCLUDE_CURRENT_DIR ON)
 | 
				
			||||||
set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${PROJECT_SOURCE_DIR}/cmake/Modules")
 | 
					set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${PROJECT_SOURCE_DIR}/cmake/Modules")
 | 
				
			||||||
set(TEASPEAK_SERVER ON)
 | 
					set(TEASPEAK_SERVER ON)
 | 
				
			||||||
 | 
					set(CMAKE_VERBOSE_MAKEFILE ON)
 | 
				
			||||||
#end now
 | 
					#end now
 | 
				
			||||||
#set(MEMORY_DEBUG_FLAGS " -fsanitize=leak -fsanitize=address -fstack-protector-all ")
 | 
					#set(MEMORY_DEBUG_FLAGS " -fsanitize=leak -fsanitize=address -fstack-protector-all ")
 | 
				
			||||||
#set(MEMORY_DEBUG_FLAGS "-fsanitize=address")
 | 
					#set(MEMORY_DEBUG_FLAGS "-fsanitize=address")
 | 
				
			||||||
@ -71,9 +70,7 @@ set(LIBRARY_PATH_GLIBC "${GLIBC_LIB_DIR}/libgio-2.0.a;${GLIBC_LIB_DIR}/libgmodul
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
add_definitions(-DINET -DINET6)
 | 
					add_definitions(-DINET -DINET6)
 | 
				
			||||||
add_subdirectory(shared/)
 | 
					add_subdirectory(shared/)
 | 
				
			||||||
add_subdirectory(client/)
 | 
					 | 
				
			||||||
add_subdirectory(server/)
 | 
					add_subdirectory(server/)
 | 
				
			||||||
add_subdirectory(license/)
 | 
					add_subdirectory(license/)
 | 
				
			||||||
add_subdirectory(flooder/)
 | 
					 | 
				
			||||||
add_subdirectory(MusicBot/)
 | 
					add_subdirectory(MusicBot/)
 | 
				
			||||||
add_subdirectory(music/)
 | 
					add_subdirectory(music/)
 | 
				
			||||||
@ -1,79 +0,0 @@
 | 
				
			|||||||
cmake_minimum_required(VERSION 3.6)
 | 
					 | 
				
			||||||
project(TeamSpeak)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -static-libgcc -static-libstdc++ -pthread ${MEMORY_DEBUG_FLAGS}")
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
include_directories(../shared/src)
 | 
					 | 
				
			||||||
add_definitions(-DLTM_DESC)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
set(SOURCE_FILES
 | 
					 | 
				
			||||||
		main.cpp
 | 
					 | 
				
			||||||
		src/protocol/Connection.cpp
 | 
					 | 
				
			||||||
		src/protocol/ConnectionHandschake.cpp
 | 
					 | 
				
			||||||
		src/protocol/ConnectionPacketHandler.cpp
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		src/protocol/socket/FilteredUDPSocket.cpp
 | 
					 | 
				
			||||||
		src/protocol/socket/RawUDPSocket.cpp
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		src/Identity.cpp
 | 
					 | 
				
			||||||
		src/MultithreadedIdentity.cpp
 | 
					 | 
				
			||||||
		src/protocol/HandshakeNew.cpp
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		../shared/src/License.cpp
 | 
					 | 
				
			||||||
)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
find_package(Protobuf REQUIRED)
 | 
					 | 
				
			||||||
include_directories(${Protobuf_INCLUDE_DIRS})
 | 
					 | 
				
			||||||
include_directories(${CMAKE_CURRENT_BINARY_DIR})
 | 
					 | 
				
			||||||
protobuf_generate_cpp(PROTO_SRCS PROTO_HDRS proto/LicenseKey.proto)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
add_executable(TeamSpeakClient ${SOURCE_FILES} ${PROTO_SRCS})
 | 
					 | 
				
			||||||
target_link_libraries(TeamSpeakClient
 | 
					 | 
				
			||||||
		${LIBRARY_PATH_THREAD_POOL}    #Static
 | 
					 | 
				
			||||||
		TeaSpeak            #Static
 | 
					 | 
				
			||||||
		TeaLicenseHelper    #Static
 | 
					 | 
				
			||||||
		TeaMusic            #Static
 | 
					 | 
				
			||||||
		${LIBRARY_PATH_TERMINAL}   #Static
 | 
					 | 
				
			||||||
		${LIBRARY_PATH_VARIBALES}
 | 
					 | 
				
			||||||
		${LIBRARY_PATH_YAML}
 | 
					 | 
				
			||||||
		pthread
 | 
					 | 
				
			||||||
		stdc++fs
 | 
					 | 
				
			||||||
		${LIBEVENT_PATH}/libevent.a
 | 
					 | 
				
			||||||
		${LIBEVENT_PATH}/libevent_pthreads.a
 | 
					 | 
				
			||||||
		opus.a
 | 
					 | 
				
			||||||
		${LIBRARY_PATH_JSON}
 | 
					 | 
				
			||||||
		${LIBRARY_PATH_PROTOBUF}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		DataPipes
 | 
					 | 
				
			||||||
		#${LIBWEBRTC_LIBRARIES} #ATTENTIAN! WebRTC does not work with crypto! (Already contains a crypto version)
 | 
					 | 
				
			||||||
		${LIBRARY_TOM_CRYPT}
 | 
					 | 
				
			||||||
		${LIBRARY_TOM_MATH}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		#We're forsed to use boringssl caused by the fact that boringssl is already within webrtc!
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		#Require a so
 | 
					 | 
				
			||||||
		sqlite3
 | 
					 | 
				
			||||||
		${LIBRARY_PATH_ED255}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		${LIBRARY_PATH_BREAKPAD}
 | 
					 | 
				
			||||||
		${LIBRARY_PATH_JDBC}
 | 
					 | 
				
			||||||
		${LIBRARY_PATH_PROTOBUF}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		${LIBRARY_PATH_BORINGSSL_SSL}
 | 
					 | 
				
			||||||
		${LIBRARY_PATH_BORINGSSL_CRYPTO}
 | 
					 | 
				
			||||||
)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#strip -s -p -v TeamSpeakHash
 | 
					 | 
				
			||||||
add_executable(TeamSpeakHash src/Identity.cpp src/MultithreadedIdentity.cpp identityHash.cpp)
 | 
					 | 
				
			||||||
#set_target_properties(TeamSpeakHash PROPERTIES CMAKE_CXX_FLAGS "-o1")
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
target_link_libraries(TeamSpeakHash
 | 
					 | 
				
			||||||
		TeaSpeak
 | 
					 | 
				
			||||||
		ThreadPoolStatic
 | 
					 | 
				
			||||||
		pthread
 | 
					 | 
				
			||||||
		${TOM_LIBRARIES}
 | 
					 | 
				
			||||||
		${LIBRARY_TOM_CRYPT}
 | 
					 | 
				
			||||||
		${LIBRARY_TOM_MATH}
 | 
					 | 
				
			||||||
		${LIBRARY_PATH_BORINGSSL_SSL}
 | 
					 | 
				
			||||||
		${LIBRARY_PATH_BORINGSSL_CRYPTO}
 | 
					 | 
				
			||||||
)
 | 
					 | 
				
			||||||
@ -1,29 +0,0 @@
 | 
				
			|||||||
#pragma once
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#include <boost/preprocessor/cat.hpp>
 | 
					 | 
				
			||||||
#include <boost/preprocessor/seq/for_each_i.hpp>
 | 
					 | 
				
			||||||
#include <boost/preprocessor/seq/enum.hpp>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#define CRYPT_MACRO(r, d, i, elem) ( elem ^ ( d - i ) )
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#define DEFINE_HIDDEN_STRING(NAME, SEED, SEQ)\
 | 
					 | 
				
			||||||
static const char* BOOST_PP_CAT(Get, NAME)()\
 | 
					 | 
				
			||||||
{\
 | 
					 | 
				
			||||||
    static char data[] = {\
 | 
					 | 
				
			||||||
        BOOST_PP_SEQ_ENUM(BOOST_PP_SEQ_FOR_EACH_I(CRYPT_MACRO, SEED, SEQ)),\
 | 
					 | 
				
			||||||
        '\0'\
 | 
					 | 
				
			||||||
    };\
 | 
					 | 
				
			||||||
\
 | 
					 | 
				
			||||||
    static bool isEncrypted = true;\
 | 
					 | 
				
			||||||
    if ( isEncrypted )\
 | 
					 | 
				
			||||||
    {\
 | 
					 | 
				
			||||||
        for (unsigned i = 0; i < ( sizeof(data) / sizeof(data[0]) ) - 1; ++i)\
 | 
					 | 
				
			||||||
        {\
 | 
					 | 
				
			||||||
            data[i] = CRYPT_MACRO(_, SEED, i, data[i]);\
 | 
					 | 
				
			||||||
        }\
 | 
					 | 
				
			||||||
\
 | 
					 | 
				
			||||||
        isEncrypted = false;\
 | 
					 | 
				
			||||||
    }\
 | 
					 | 
				
			||||||
\
 | 
					 | 
				
			||||||
    return data;\
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
@ -1,27 +0,0 @@
 | 
				
			|||||||
[OUT] clientinitiv alpha=kXZSTZ7qaOhblA== omega=MEwDAgcAAgEgAiA5+ycSoMRRdugndbohYtH7PqS6Q6h3TV1VnGRKoZNMsQIhANn2rszHVipB13LBcY2Zf3APg7HX7ix3WWiaT5hjQrUv ot=1 ip=84.200.62.248
 | 
					 | 
				
			||||||
[ IN] initivexpand2 l=AQCBIiOUkbXLeQ\/6UhNB+8iJnwLYGZJglZoDFSTt+7awWgAJFtlwLxmo8AAAACVUZWFtU3BlYWsgU3lzdGVtcyBHbWJIAADtwskuiFg0FkafvNvS1uwz67b2lEhMnOkAygPvo0waGAAJQrh2HBxqvQAAACRUZWFtU3BlYWsgc3lzdGVtcyBHbWJIAADd85KDiA8UeqB5G9MBtNZ879CYBnfbjc\/OVj0j0xMcqQIJQ7qACi5lgAYAAAAAVGVhbVNwZWFrIFN5c3RlbXMgR21iSAAAitZK9P6JEXiiy+uERaapfw\/I5na7S5M+Se5IoOb\/24kgCV6OnAlfN1w= beta=5cB\/vUHLQ7GbVPNRStMLnZlyo572IFPzdgTTgxJ3zF4JBehh7nLudpdzk1hdbcglx4n3JmqX omega=MEwDAgcAAgEgAiEA83r2Er9vHr5sSEcm9g\/\/rdLjOdTMtwX\/Lkbi02+24FkCIB2P804l26yketcG8WxZQJ1z4ukU0e3SqEzm4pKHzMRY ot=1 proof=MEUCIAgYSvrPo0OKKD8aRmjeKVS1EVF6L\/DXLBT+XFkZlMVPAiEAnSMVOp8DOEMzcE42hna72+aWr+Z4+a76x23hmDJa4Uk= tvd=AQAAAABaQjKEblQQgGczKfB+CSS7IY5qli8LRS9jDltkab8leo6ltwQH82VUU\/WwnpCbazVbnh4iNbcobdxv\/MTX5Y3+6xpqDgEAEa1\/SLpE\/CIg2X7GX9mtDCCvP1KdQGaT\/RKoofPSsTkACRbZcAr4DPAAAAASVGVhbVNwZWFrIFN5c3RlbXMgR21iSAAAPgFaQLsu0h3FTQax+i0qXFXX\/Bn7VcGJH8SE5AOAiuQECVvUYwlenQk= time=1514211836
 | 
					 | 
				
			||||||
[OUT] clientek ek=n4+LesWAJf+8ha6LlF5kWilUbj59qX+zV31asaniK8U= proof=MEQCIC+NxeqTNUQWqHz914BHkFfC3LTF8BkYAYktMB62sET7AiBPmnfN6yoB381g\/GAnZVwMkeCPIjKi9vHUk15yOdT5FQ==
 | 
					 | 
				
			||||||
[OUT] clientinit client_nickname=P3nisBaum client_version=3.1.7\s[Build:\s1513163251] client_platform=Windows client_input_hardware=1 client_output_hardware=1 client_default_channel client_default_channel_password client_server_password client_meta_data client_version_sign=tdNngCAZ1ImAf7BxJzO4RXv5nBRsUERsrSOnMKVUFNQg6BS4Bzag0RFgLVzs2DRj19AC8+q5cXgH+5Ms50mTCA== client_key_offset=15848377 client_nickname_phonetic client_default_token client_badges=Overwolf=0 hwid=3036580947951600a7de06cd796bb0f1,7209e96ac1f60ff7772b7301919e0878
 | 
					 | 
				
			||||||
[OUT] clientinit client_nickname=P3nisBaum client_version=3.1.7\s[Build:\s1513163251] client_platform=Windows client_input_hardware=1 client_output_hardware=1 client_default_channel client_default_channel_password client_server_password client_meta_data client_version_sign=tdNngCAZ1ImAf7BxJzO4RXv5nBRsUERsrSOnMKVUFNQg6BS4Bzag0RFgLVzs2DRj19AC8+q5cXgH+5Ms50mTCA== client_key_offset=15848377 client_nickname_phonetic client_default_token client_badges=Overwolf=0 hwid=3036580947951600a7de06cd796bb0f1,7209e96ac1f60ff7772b7301919e0878
 | 
					 | 
				
			||||||
[ IN] error id=521 msg=too\smany\sclones\salready\sconnected
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
-> ot & ip needs to be set
 | 
					 | 
				
			||||||
-> ack needs to be unencripted as look clientinitiv not done
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
initivexpand2 l=AQCBIiOUkbXLeQ\/6UhNB+8iJnwLYGZJglZoDFSTt+7awWgAJFtlwLxmo8AAAACVUZWFtU3BlYWsgU3lzdGVtcyBHbWJIAADtwskuiFg0FkafvNvS1uwz67b2lEhMnOkAygPvo0waGAAJQrh2HBxqvQAAACRUZWFtU3BlYWsgc3lzdGVtcyBHbWJIAADd85KDiA8UeqB5G9MBtNZ879CYBnfbjc\/OVj0j0xMcqQIJQ7qACi5lgAYAAAAAVGVhbVNwZWFrIFN5c3RlbXMgR21iSAAA5Szd\/YkuL5NUF7SeHfvSKi5byOOMvYME0\/WRwlTHK8ogCV6hYglfSiI= beta=W\/D9NTwuZi6L1sbFpA+KiDBMSgl8y6Jy6vFVSGszJy1BPy8zEhNDQ62msazyAgk0CdbY0B+E omega=MEwDAgcAAgEgAiEA83r2Er9vHr5sSEcm9g\/\/rdLjOdTMtwX\/Lkbi02+24FkCIB2P804l26yketcG8WxZQJ1z4ukU0e3SqEzm4pKHzMRY ot=1 proof=MEUCIA3dgrIlXFIjkLrxJ1Yni7OqQYwPing03Xz\/zkQFrmdHAiEA8a0delCktJ21TIrj91QZbA76vtZUL38XVm+P2bR9M7c= tvd=AQAAAABaQjKEblQQgGczKfB+CSS7IY5qli8LRS9jDltkab8leo6ltwQH82VUU\/WwnpCbazVbnh4iNbcobdxv\/MTX5Y3+6xpqDgEAEa1\/SLpE\/CIg2X7GX9mtDCCvP1KdQGaT\/RKoofPSsTkACRbZcAr4DPAAAAASVGVhbVNwZWFrIFN5c3RlbXMgR21iSAAAPgFaQLsu0h3FTQax+i0qXFXX\/Bn7VcGJH8SE5AOAiuQECVvUYwlenQk= time=1514216642
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
Nr 1
 | 
					 | 
				
			||||||
[OUT] clientinitiv alpha=DBiidVqi8kTYAQ== omega=MEwDAgcAAgEgAiA5+ycSoMRRdugndbohYtH7PqS6Q6h3TV1VnGRKoZNMsQIhANn2rszHVipB13LBcY2Zf3APg7HX7ix3WWiaT5hjQrUv ot=1 ip=84.200.62.248
 | 
					 | 
				
			||||||
[ IN] initivexpand2 l=AQCBIiOUkbXLeQ\/6UhNB+8iJnwLYGZJglZoDFSTt+7awWgAJFtlwLxmo8AAAACVUZWFtU3BlYWsgU3lzdGVtcyBHbWJIAADtwskuiFg0FkafvNvS1uwz67b2lEhMnOkAygPvo0waGAAJQrh2HBxqvQAAACRUZWFtU3BlYWsgc3lzdGVtcyBHbWJIAADd85KDiA8UeqB5G9MBtNZ879CYBnfbjc\/OVj0j0xMcqQIJQ7qACi5lgAYAAAAAVGVhbVNwZWFrIFN5c3RlbXMgR21iSAAALYVev\/rqwinxd2zrGZla8+69t03410Iyo9N6lV7bajMgCV6ioQlfS2E= beta=\/Eg8SA2j45sSVi28kVwBVpxT98G1w0tlenDVYuKy\/7Cn1ZZiNiwu8Z9XhGBxwrzPXrMHPEMJ omega=MEwDAgcAAgEgAiEA83r2Er9vHr5sSEcm9g\/\/rdLjOdTMtwX\/Lkbi02+24FkCIB2P804l26yketcG8WxZQJ1z4ukU0e3SqEzm4pKHzMRY ot=1 proof=MEUCIFFa+q1zdgA0OtXgdgn9gxSOMp7GBvc3vPW0YDTU2+e6AiEA8sjW3XDikxQADPoSaSw7lwL6gfXr6gwO0Hvro3RZBHU= tvd=AQAAAABaQjKEblQQgGczKfB+CSS7IY5qli8LRS9jDltkab8leo6ltwQH82VUU\/WwnpCbazVbnh4iNbcobdxv\/MTX5Y3+6xpqDgEAEa1\/SLpE\/CIg2X7GX9mtDCCvP1KdQGaT\/RKoofPSsTkACRbZcAr4DPAAAAASVGVhbVNwZWFrIFN5c3RlbXMgR21iSAAAPgFaQLsu0h3FTQax+i0qXFXX\/Bn7VcGJH8SE5AOAiuQECVvUYwlenQk= time=1514216961
 | 
					 | 
				
			||||||
[OUT] clientek ek=19doGY4WwwAeW\/zHnmFJTpnE8h9MUJZSYFNpz4aUabs= proof=MEUCIGTwtZ1E+HjDPLqlyTuaHtvWmjYW\/\/tnQgugaC5u1swtAiEA9DN+kuwxuXG80FDzKnICGQYQGZZBySQv8Nhflg\/1FwQ=
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
[OUT] clientinitiv alpha=3Pcn19zISkIB5g== omega=MEwDAgcAAgEgAiA5+ycSoMRRdugndbohYtH7PqS6Q6h3TV1VnGRKoZNMsQIhANn2rszHVipB13LBcY2Zf3APg7HX7ix3WWiaT5hjQrUv ot=1 ip=84.200.62.248
 | 
					 | 
				
			||||||
[ IN] initivexpand2 l=AQCBIiOUkbXLeQ\/6UhNB+8iJnwLYGZJglZoDFSTt+7awWgAJFtlwLxmo8AAAACVUZWFtU3BlYWsgU3lzdGVtcyBHbWJIAADtwskuiFg0FkafvNvS1uwz67b2lEhMnOkAygPvo0waGAAJQrh2HBxqvQAAACRUZWFtU3BlYWsgc3lzdGVtcyBHbWJIAADd85KDiA8UeqB5G9MBtNZ879CYBnfbjc\/OVj0j0xMcqQIJQ7qACi5lgAYAAAAAVGVhbVNwZWFrIFN5c3RlbXMgR21iSAAASpEEQfPJOP8aeecPLtzcu8iYmtqBJn8MWq+8lSQljYcgCV6iyAlfS4g= beta=JLFcgyWwlYNzy5lsTGJKGz6rvmShHrb6YEZfq4TXwTLSiWDGqckf6ywiMOP2MGAc1y1yQsEi omega=MEwDAgcAAgEgAiEA83r2Er9vHr5sSEcm9g\/\/rdLjOdTMtwX\/Lkbi02+24FkCIB2P804l26yketcG8WxZQJ1z4ukU0e3SqEzm4pKHzMRY ot=1 proof=MEYCIQCpKZJCmQCHyC2PLIleZVAl1fSTdnzqcNxhiXxVAHtUHgIhAPvPfziHtiqn36nB7KSVuKV+gMA29OL87bI1HP6CJNw2 tvd=AQAAAABaQjKEblQQgGczKfB+CSS7IY5qli8LRS9jDltkab8leo6ltwQH82VUU\/WwnpCbazVbnh4iNbcobdxv\/MTX5Y3+6xpqDgEAEa1\/SLpE\/CIg2X7GX9mtDCCvP1KdQGaT\/RKoofPSsTkACRbZcAr4DPAAAAASVGVhbVNwZWFrIFN5c3RlbXMgR21iSAAAPgFaQLsu0h3FTQax+i0qXFXX\/Bn7VcGJH8SE5AOAiuQECVvUYwlenQk= time=1514217000
 | 
					 | 
				
			||||||
[OUT] clientek ek=yGZb1Qp0Y\/V7T+rMwcqtzUeOTIGgE6+7gcKxAw2OMPU= proof=MEQCIHdgsGlufstf\/ab1TvvM740Azs56jyGFmo93ijr53k1FAiBHNhWkV9xLUG19jpZGGe86SgCDli7GdSrv61ZGr3jD9g==
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
bM5HB+Ox/Wht38dd6/VeB7L76ebcpP9YgKzWAk4lmQ8= 
 | 
					 | 
				
			||||||
@ -1,63 +0,0 @@
 | 
				
			|||||||
#include <iostream>
 | 
					 | 
				
			||||||
#include <src/Identity.h>
 | 
					 | 
				
			||||||
#include <sstream>
 | 
					 | 
				
			||||||
#include "HideString.h"
 | 
					 | 
				
			||||||
DEFINE_HIDDEN_STRING(HeaderMessage, 0x44, ('#')('#')('#')('#')('#')('#')('#')('#')('#')('#')('#')('#')('#')('#')('#')('#')('#')(' ')('T')('S')('3')(' ')('H')('a')('s')('h')(' ')('b')('y')(' ')('W')('o')('l')('v')('e')('r')('i')('n')('D')('E')('V')(' ')('#')('#')('#')('#')('#')('#')('#')('#')('#')('#')('#')('#')('#')('#')('#')('#')('#'));
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
using namespace ts;
 | 
					 | 
				
			||||||
using namespace std;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
inline string crypt(string in){
 | 
					 | 
				
			||||||
    stringstream result;
 | 
					 | 
				
			||||||
    result << "DEFINE_HIDDEN_STRING(EncryptionKey, 0xA5, ";
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    for(char c : in)
 | 
					 | 
				
			||||||
        result << "('" << c << "')";
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    result << ");";
 | 
					 | 
				
			||||||
    return result.str();
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
int main(int argc, char** argv) {
 | 
					 | 
				
			||||||
    cout << GetHeaderMessage() << endl;
 | 
					 | 
				
			||||||
    if(argc < 3) {
 | 
					 | 
				
			||||||
        cerr << "Invalid arguments. ./TSHash <threads> <MaxLevel> [<BlockSize> = 1.000.000]" << endl;
 | 
					 | 
				
			||||||
        return 0;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    init_LTM();
 | 
					 | 
				
			||||||
    if(register_prng(&sprng_desc) == -1) {
 | 
					 | 
				
			||||||
        cerr << "could not setup prng" << endl;
 | 
					 | 
				
			||||||
        return EXIT_FAILURE;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    if (register_cipher(&rijndael_desc) == -1) {
 | 
					 | 
				
			||||||
        cerr << "could not setup rijndael" << endl;
 | 
					 | 
				
			||||||
        return EXIT_FAILURE;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    int threads = atoi(argv[1]);
 | 
					 | 
				
			||||||
    int level = atoi(argv[2]);
 | 
					 | 
				
			||||||
    int blockSize = argc > 3 ? atoi(argv[3]) : 1 * 1000 * 1000;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    cout << "# Creating new identity (Threads: " << threads << " Level: " << level << " Size: " << blockSize << ")" << endl;
 | 
					 | 
				
			||||||
    auto identity = Identity::createNew();
 | 
					 | 
				
			||||||
    cout << "IDENTITY: " << identity->exportIdentity() << endl;
 | 
					 | 
				
			||||||
    cout << "# Start hashing" << endl;
 | 
					 | 
				
			||||||
    if(!identity->improveSecurityLevelMultithreaded(level, threads, blockSize, 0, true)) {
 | 
					 | 
				
			||||||
        cout << "ERROR: Could not improve identity!" << endl;
 | 
					 | 
				
			||||||
        return 1;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    cout << "INFO: Found identity!" << endl;
 | 
					 | 
				
			||||||
    cout << "IDENTITY: " << identity->exportIdentity() << endl;
 | 
					 | 
				
			||||||
    cout << "LEVEL: " << identity->getSecurityLevel() << endl;
 | 
					 | 
				
			||||||
    return 0;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
/*
 | 
					 | 
				
			||||||
#IDENTITY: 5513931022VPXfjXSN1qRa2IZvTpS3xs+L7YvcBI2lTfXgOWAkaAQwQVgR8BXtWJ1MKUSh/HGNGNgdVGWYHcCg1BgQie3pValZZB39hVE4HBStcAA5SUz9Tf1JbXVABBVUJUwFmFkJZLlZUfCtaZXFBaUVBZ1poOXlQd09KSzN6ejYxMjVnaGN3bmtSKzRPOXdvZWJObVpaT3gyOTA3ND0=
 | 
					 | 
				
			||||||
#LEVEL: 36
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#IDENTITY: 0VdYzXyIWNlPR991zQZLQoGLDYA4JvCX9GQ3MAYzpBRABWAHZTAmJvNQUAMxEEKGQDJVlnanF1YDdQQn0GewlXVWoAQmVMLX9FVyZaMAI7KlAIeXpPKGMCJ3BTVAJHLGlUHARbBlpqSUNJUURISXY1UXJCYmlBMHlZOVV3dFdRRXovM0lkU1hzNFJvWTkwT1JienA5bVRRPT0=
 | 
					 | 
				
			||||||
Current level = 41 at 1233527956186
 | 
					 | 
				
			||||||
Current offset index: 3750576000000 block size: 1000000
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
*/
 | 
					 | 
				
			||||||
							
								
								
									
										1176
									
								
								client/main.cpp
									
									
									
									
									
								
							
							
						
						
									
										1176
									
								
								client/main.cpp
									
									
									
									
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							@ -1,17 +0,0 @@
 | 
				
			|||||||
syntax = "proto2";
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
package ts.proto.license.teamspeak;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
message LicenseData { //_ZTIN3com10teamspeak310accounting8protobuf19Signed_License_InfoE => Signed_License_Info
 | 
					 | 
				
			||||||
    required bytes chain            = 1;
 | 
					 | 
				
			||||||
    required bytes root             = 2;
 | 
					 | 
				
			||||||
    required int32  slots           = 3;
 | 
					 | 
				
			||||||
    required int32  servers         = 4;
 | 
					 | 
				
			||||||
    required string type            = 5;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
message License {
 | 
					 | 
				
			||||||
    required LicenseData license    = 1;
 | 
					 | 
				
			||||||
    required bytes sign_chain       = 2;
 | 
					 | 
				
			||||||
    required bytes license_sign     = 3;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
@ -1,218 +0,0 @@
 | 
				
			|||||||
//
 | 
					 | 
				
			||||||
// Created by wolverindev on 07.10.17.
 | 
					 | 
				
			||||||
//
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#include <iostream>
 | 
					 | 
				
			||||||
#include <openssl/sha.h>
 | 
					 | 
				
			||||||
#include "misc/base64.h"
 | 
					 | 
				
			||||||
#include "Identity.h"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#define ECC_TYPE_INDEX 5
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
using namespace std;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static const char *TSKEY =
 | 
					 | 
				
			||||||
                "b9dfaa7bee6ac57ac7b65f1094a1c155"
 | 
					 | 
				
			||||||
                "e747327bc2fe5d51c512023fe54a2802"
 | 
					 | 
				
			||||||
                "01004e90ad1daaae1075d53b7d571c30"
 | 
					 | 
				
			||||||
                "e063b5a62a4a017bb394833aa0983e6e";
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static int obfuscateInplace(char *data, uint32_t length) {
 | 
					 | 
				
			||||||
    int dataSize = min((uint32_t) 100, length);
 | 
					 | 
				
			||||||
    for (int i = 0; i < dataSize; i++) {
 | 
					 | 
				
			||||||
        data[i] ^= TSKEY[i];
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    char hash[20];
 | 
					 | 
				
			||||||
    hash_state ctx;
 | 
					 | 
				
			||||||
    if (sha1_init(&ctx) != CRYPT_OK)
 | 
					 | 
				
			||||||
    { return -1; }
 | 
					 | 
				
			||||||
    if (sha1_process(&ctx, (uint8_t*)data + 20, strlen(data + 20)) != CRYPT_OK)
 | 
					 | 
				
			||||||
    { return -1; }
 | 
					 | 
				
			||||||
    if (sha1_done(&ctx, (uint8_t*)hash) != CRYPT_OK)
 | 
					 | 
				
			||||||
    { return -1; }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    for (int i = 0; i < 20; i++) {
 | 
					 | 
				
			||||||
        data[i] ^= hash[i];
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    return 0;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static int deObfuscateInplace(char *data, uint32_t length) {
 | 
					 | 
				
			||||||
    char hash[20];
 | 
					 | 
				
			||||||
    hash_state ctx;
 | 
					 | 
				
			||||||
    if (sha1_init(&ctx) != CRYPT_OK)
 | 
					 | 
				
			||||||
    { return -1; }
 | 
					 | 
				
			||||||
    if (sha1_process(&ctx, (uint8_t*)data + 20, strlen(data + 20)) != CRYPT_OK)
 | 
					 | 
				
			||||||
    { return -1; }
 | 
					 | 
				
			||||||
    if (sha1_done(&ctx, (uint8_t*)hash) != CRYPT_OK)
 | 
					 | 
				
			||||||
    { return -1; }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    for (int i = 0; i < 20; i++) {
 | 
					 | 
				
			||||||
        data[i] ^= hash[i];
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    int dataSize = min((uint32_t) 100, length);
 | 
					 | 
				
			||||||
    for (int i = 0; i < dataSize; i++) {
 | 
					 | 
				
			||||||
        data[i] ^= TSKEY[i];
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    return 0;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
namespace ts {
 | 
					 | 
				
			||||||
    Identity* Identity::createNew() {
 | 
					 | 
				
			||||||
        auto result = new Identity();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        prng_state rndState{};
 | 
					 | 
				
			||||||
        memset(&rndState, 0, sizeof(prng_state));
 | 
					 | 
				
			||||||
        int err;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        result->keyPair = new ecc_key;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        cout << " -> " << find_prng("sprng") << endl;
 | 
					 | 
				
			||||||
        if((err = ecc_make_key_ex(&rndState, find_prng("sprng"), result->keyPair, <c_ecc_sets[ECC_TYPE_INDEX])) != CRYPT_OK) {
 | 
					 | 
				
			||||||
            cerr << "Cant create a new identity (Keygen)" << endl;
 | 
					 | 
				
			||||||
            cerr << "Message: " << error_to_string(err) << endl;
 | 
					 | 
				
			||||||
            delete result;
 | 
					 | 
				
			||||||
            return nullptr;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        return result;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    Identity::Identity(std::string asnStruct, int64_t keyOffset, int64_t lastCheckedOffset) {
 | 
					 | 
				
			||||||
        this->keyOffset = keyOffset;
 | 
					 | 
				
			||||||
        this->lastCheckedOffset = lastCheckedOffset;
 | 
					 | 
				
			||||||
        importKey(asnStruct);
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    Identity::Identity(std::string data) : Identity() {
 | 
					 | 
				
			||||||
        int vindex = data.find('V');
 | 
					 | 
				
			||||||
        assert(vindex > 0);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        auto slevel = data.substr(0, vindex);
 | 
					 | 
				
			||||||
        assert(slevel.find_first_not_of("0123456789") == std::string::npos);
 | 
					 | 
				
			||||||
        this->keyOffset = stol(slevel);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        data = data.substr(vindex + 1);
 | 
					 | 
				
			||||||
        data = base64::decode(data);
 | 
					 | 
				
			||||||
        if(deObfuscateInplace((char *) data.data(), data.length()) < 0) {
 | 
					 | 
				
			||||||
            cerr << "Cand decript identitry data" << endl;
 | 
					 | 
				
			||||||
            return;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        importKey(base64::decode(data));
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    Identity::Identity() {
 | 
					 | 
				
			||||||
        this->keyOffset = 0;
 | 
					 | 
				
			||||||
        this->lastCheckedOffset = 0;
 | 
					 | 
				
			||||||
        this->keyPair = nullptr;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    Identity::~Identity() {
 | 
					 | 
				
			||||||
        delete this->keyPair;
 | 
					 | 
				
			||||||
        this->keyPair = nullptr;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    void Identity::importKey(std::string asnStruct) {
 | 
					 | 
				
			||||||
        this->keyPair = new ecc_key;
 | 
					 | 
				
			||||||
        int err;
 | 
					 | 
				
			||||||
        if((err = ecc_import_ex((const unsigned char *) asnStruct.data(), asnStruct.length(), this->keyPair, <c_ecc_sets[ECC_TYPE_INDEX])) != CRYPT_OK){
 | 
					 | 
				
			||||||
            delete this->keyPair;
 | 
					 | 
				
			||||||
            this->keyPair = nullptr;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            cerr << "Cant import identity from asn structure" << endl;
 | 
					 | 
				
			||||||
            cerr << "Message: " << error_to_string(err) << endl;
 | 
					 | 
				
			||||||
            return;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    std::string Identity::exportIdentity() {
 | 
					 | 
				
			||||||
        string data = privateKey();
 | 
					 | 
				
			||||||
        obfuscateInplace((char *) data.data(), data.length());
 | 
					 | 
				
			||||||
        return to_string(this->lastValidKeyOffset()) + "V" + base64_encode(data);
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    std::string Identity::publicKey() {
 | 
					 | 
				
			||||||
        assert(this->keyPair);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        size_t bufferLength = 1028;
 | 
					 | 
				
			||||||
        char buffer[bufferLength];
 | 
					 | 
				
			||||||
        ecc_export((unsigned char *) buffer, &bufferLength, PK_PUBLIC, this->keyPair);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        return base64_encode(string(buffer, bufferLength));
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    std::string Identity::privateKey() {
 | 
					 | 
				
			||||||
        assert(this->keyPair);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        size_t bufferLength = 1028;
 | 
					 | 
				
			||||||
        char buffer[bufferLength];
 | 
					 | 
				
			||||||
        ecc_export((unsigned char *) buffer, &bufferLength, PK_PRIVATE, this->keyPair);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        return base64_encode(string(buffer, bufferLength));
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    ecc_key& Identity::getPrivateKey() {
 | 
					 | 
				
			||||||
        return *keyPair;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    #define MaxUlongString 20
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    bool Identity::improveSecurityLevel(int target) {
 | 
					 | 
				
			||||||
        auto publicKey = this->publicKey();
 | 
					 | 
				
			||||||
        char hashBuffer[publicKey.length() + MaxUlongString];
 | 
					 | 
				
			||||||
        memcpy(hashBuffer, publicKey.data(), publicKey.length());
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        this->lastCheckedOffset = max(this->lastCheckedOffset, this->keyOffset);
 | 
					 | 
				
			||||||
        int best = getSecurityLevel(hashBuffer, publicKey.length(), this->lastCheckedOffset);
 | 
					 | 
				
			||||||
        while(true){
 | 
					 | 
				
			||||||
            if(best >= target) return true;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            int currentLevel = getSecurityLevel(hashBuffer, publicKey.length(), this->lastCheckedOffset);
 | 
					 | 
				
			||||||
            if(currentLevel >= best){
 | 
					 | 
				
			||||||
                this->keyOffset = this->lastCheckedOffset;
 | 
					 | 
				
			||||||
                best = currentLevel;
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
            this->lastCheckedOffset++;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    int Identity::getSecurityLevel() {
 | 
					 | 
				
			||||||
        auto length = publicKey().length();
 | 
					 | 
				
			||||||
        char hashBuffer[length + MaxUlongString];
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        auto publicKey = this->publicKey();
 | 
					 | 
				
			||||||
        memcpy(hashBuffer, publicKey.data(), publicKey.length());
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        return getSecurityLevel(hashBuffer, publicKey.length(), this->keyOffset);
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    int Identity::getSecurityLevel(char *hashBuffer, size_t keyLength, int64_t offset) {
 | 
					 | 
				
			||||||
        char numBuffer[MaxUlongString];
 | 
					 | 
				
			||||||
        int numLen = 0;
 | 
					 | 
				
			||||||
        do {
 | 
					 | 
				
			||||||
            numBuffer[numLen] = '0' + (offset % 10);
 | 
					 | 
				
			||||||
            offset /= 10;
 | 
					 | 
				
			||||||
            numLen++;
 | 
					 | 
				
			||||||
        } while(offset > 0);
 | 
					 | 
				
			||||||
        for(int i = 0; i < numLen; i++)
 | 
					 | 
				
			||||||
            hashBuffer[keyLength + i] = numBuffer[numLen - (i + 1)];
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        char shaBuffer[SHA_DIGEST_LENGTH];
 | 
					 | 
				
			||||||
        SHA1((const unsigned char *) hashBuffer, keyLength + numLen, (unsigned char *) shaBuffer);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        //Leading zero bits
 | 
					 | 
				
			||||||
        register int zeroBits = 0;
 | 
					 | 
				
			||||||
        register int i;
 | 
					 | 
				
			||||||
        for(i = 0; i < SHA_DIGEST_LENGTH; i++)
 | 
					 | 
				
			||||||
            if(shaBuffer[i] == 0) zeroBits += 8;
 | 
					 | 
				
			||||||
            else break;
 | 
					 | 
				
			||||||
        if(i < SHA_DIGEST_LENGTH)
 | 
					 | 
				
			||||||
            for(int bit = 0; bit < 8; bit++)
 | 
					 | 
				
			||||||
                if((shaBuffer[i] & (1 << bit)) == 0) zeroBits++;
 | 
					 | 
				
			||||||
                else break;
 | 
					 | 
				
			||||||
        return zeroBits;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
@ -1,44 +0,0 @@
 | 
				
			|||||||
#pragma once
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#include <tomcrypt.h>
 | 
					 | 
				
			||||||
#include <string>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
namespace ts {
 | 
					 | 
				
			||||||
    class Identity {
 | 
					 | 
				
			||||||
        public:
 | 
					 | 
				
			||||||
            static Identity* createNew();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            explicit Identity(std::string data);
 | 
					 | 
				
			||||||
            Identity(std::string asnStruct,int64_t keyOffset,int64_t lastCheckedOffset);
 | 
					 | 
				
			||||||
            ~Identity();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            bool valid(){ return keyPair != nullptr; }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            std::string publicKey();
 | 
					 | 
				
			||||||
            std::string privateKey();
 | 
					 | 
				
			||||||
            std::string exportIdentity();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            ecc_key* getKeyPair(){
 | 
					 | 
				
			||||||
                return keyPair;
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            ecc_key& getPrivateKey();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            bool improveSecurityLevel(int target);
 | 
					 | 
				
			||||||
            bool improveSecurityLevelMultithreaded(int target, int nthread = 4, size_t nblockSize = 1000, size_t baseOffset = 0, bool verbose = false);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            int getSecurityLevel();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            int64_t lastValidKeyOffset(){ return keyOffset; }
 | 
					 | 
				
			||||||
            int64_t lastTestedKeyOffset(){ return lastCheckedOffset; }
 | 
					 | 
				
			||||||
        private:
 | 
					 | 
				
			||||||
            Identity();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            int getSecurityLevel(char* hasBuffer, size_t keyLength, int64_t offset);
 | 
					 | 
				
			||||||
            void importKey(std::string asn1);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            ecc_key* keyPair = nullptr;
 | 
					 | 
				
			||||||
            size_t keyOffset;
 | 
					 | 
				
			||||||
            size_t lastCheckedOffset;
 | 
					 | 
				
			||||||
    };
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
@ -1,189 +0,0 @@
 | 
				
			|||||||
//
 | 
					 | 
				
			||||||
// Created by wolverindev on 14.10.17.
 | 
					 | 
				
			||||||
//
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#include <iostream>
 | 
					 | 
				
			||||||
#include <openssl/sha.h>
 | 
					 | 
				
			||||||
#include <ThreadPool/Thread.h>
 | 
					 | 
				
			||||||
#include <vector>
 | 
					 | 
				
			||||||
#include <ThreadPool/Mutex.h>
 | 
					 | 
				
			||||||
#include <zconf.h>
 | 
					 | 
				
			||||||
#include "misc/base64.h"
 | 
					 | 
				
			||||||
#include "Identity.h"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#define ECC_TYPE_INDEX 5
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#define USE_OPENSSL_SHA1
 | 
					 | 
				
			||||||
using namespace std::chrono;
 | 
					 | 
				
			||||||
using namespace std;
 | 
					 | 
				
			||||||
namespace ts {
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    inline int calculateSecutityLevel(uint8_t* hashBuffer, uint8_t* bufferToHash, int length){
 | 
					 | 
				
			||||||
        register int zeroBits = 0;
 | 
					 | 
				
			||||||
        register int bit;
 | 
					 | 
				
			||||||
        register int i;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        SHA1(bufferToHash, length, hashBuffer);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        //Leading zero bits
 | 
					 | 
				
			||||||
        for(i = 0; i < SHA_DIGEST_LENGTH; i++)
 | 
					 | 
				
			||||||
            if(hashBuffer[i] == 0) zeroBits += 8;
 | 
					 | 
				
			||||||
            else break;
 | 
					 | 
				
			||||||
        if(i < SHA_DIGEST_LENGTH)
 | 
					 | 
				
			||||||
            for(bit = 0; bit < 8; bit++)
 | 
					 | 
				
			||||||
                if((hashBuffer[i] & (1 << bit)) == 0) zeroBits++;
 | 
					 | 
				
			||||||
                else break;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        return zeroBits;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    inline void increaseNumBuffer(char* buffer, int numOffset, int* length){
 | 
					 | 
				
			||||||
        int index = *length - 1;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        while(true){
 | 
					 | 
				
			||||||
            if(buffer[index] == '9'){
 | 
					 | 
				
			||||||
                if(index - 1 < numOffset) {
 | 
					 | 
				
			||||||
                    buffer[index] = '1';
 | 
					 | 
				
			||||||
                    buffer[*length] = '0';
 | 
					 | 
				
			||||||
                    *length += 1;
 | 
					 | 
				
			||||||
                    return;
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
                buffer[index--] = '0';
 | 
					 | 
				
			||||||
            } else {
 | 
					 | 
				
			||||||
                buffer[index] += 1;
 | 
					 | 
				
			||||||
                return;
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#define MaxUlongString 20
 | 
					 | 
				
			||||||
    bool Identity::improveSecurityLevelMultithreaded(int target, int nthread, size_t nblockSize, size_t baseOffset, bool verbose) {
 | 
					 | 
				
			||||||
        if(this->getSecurityLevel() >= target)
 | 
					 | 
				
			||||||
            return false;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        vector<threads::Thread*> threads;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        auto publicKey = this->publicKey();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        size_t currentBlockIndex = max(max(this->lastCheckedOffset, this->keyOffset), baseOffset);
 | 
					 | 
				
			||||||
        threads::Mutex blockIndexLock;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        auto activeDigging = new bool(true);
 | 
					 | 
				
			||||||
        threads::Thread* thread;
 | 
					 | 
				
			||||||
        for(int threadId = 0; threadId < nthread; threadId++){
 | 
					 | 
				
			||||||
            thread = new threads::Thread([&](){
 | 
					 | 
				
			||||||
                size_t offset = 0;
 | 
					 | 
				
			||||||
                size_t endOffset = 0;
 | 
					 | 
				
			||||||
                size_t bestOffset = 0;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                char shaHashBuffer[SHA_DIGEST_LENGTH];
 | 
					 | 
				
			||||||
                char hashBuffer[publicKey.length() + MaxUlongString];
 | 
					 | 
				
			||||||
                memcpy(hashBuffer, publicKey.data(), publicKey.length());
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#ifndef SLOW
 | 
					 | 
				
			||||||
                //Setup some stuff
 | 
					 | 
				
			||||||
                size_t pubKeyLength = publicKey.length();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
                while(*activeDigging){
 | 
					 | 
				
			||||||
                    //Get next range
 | 
					 | 
				
			||||||
                    blockIndexLock.lock();
 | 
					 | 
				
			||||||
                    offset = currentBlockIndex;
 | 
					 | 
				
			||||||
                    endOffset = currentBlockIndex + nblockSize;
 | 
					 | 
				
			||||||
                    currentBlockIndex += nblockSize;
 | 
					 | 
				
			||||||
                    blockIndexLock.unlock();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                    int bestLevel = this->getSecurityLevel(hashBuffer, publicKey.length(), this->keyOffset);
 | 
					 | 
				
			||||||
#ifdef SLOW
 | 
					 | 
				
			||||||
                    while(offset < endOffset){
 | 
					 | 
				
			||||||
                        int currentLevel = getSecurityLevel(hashBuffer, publicKey.length(), offset);
 | 
					 | 
				
			||||||
                        if(currentLevel >= best){
 | 
					 | 
				
			||||||
                            bestOffset = offset;
 | 
					 | 
				
			||||||
                            best = currentLevel;
 | 
					 | 
				
			||||||
                        }
 | 
					 | 
				
			||||||
                        offset++;
 | 
					 | 
				
			||||||
                    }
 | 
					 | 
				
			||||||
                    blockIndexLock.lock();
 | 
					 | 
				
			||||||
                    if(best > this->getSecurityLevel()){
 | 
					 | 
				
			||||||
                        if(verbose) cout << "Improved -> " << best << "/" << target << endl;
 | 
					 | 
				
			||||||
                        this->lastCheckedOffset = bestOffset;
 | 
					 | 
				
			||||||
                        this->keyOffset = bestOffset;
 | 
					 | 
				
			||||||
                        cout << "Got level: " << best << endl;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                        if(best >= target){
 | 
					 | 
				
			||||||
                            cout << "Done!" << endl;
 | 
					 | 
				
			||||||
                            *activeDigging = false;
 | 
					 | 
				
			||||||
                        }
 | 
					 | 
				
			||||||
                    }
 | 
					 | 
				
			||||||
                    blockIndexLock.unlock();
 | 
					 | 
				
			||||||
                    if(verbose) cout << "round done: highest -> " << best << endl;
 | 
					 | 
				
			||||||
#else
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                    string strStartOffset = to_string(offset);
 | 
					 | 
				
			||||||
                    ssize_t roundsLeft = nblockSize;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                    auto hashBufferLength = static_cast<int>(publicKey.length() + strStartOffset.length());
 | 
					 | 
				
			||||||
                    memcpy(&hashBuffer[pubKeyLength], strStartOffset.c_str(), strStartOffset.length());
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                    while(roundsLeft-- >= 0){
 | 
					 | 
				
			||||||
                        auto level = calculateSecutityLevel(reinterpret_cast<uint8_t *>(shaHashBuffer), reinterpret_cast<uint8_t *>(hashBuffer), hashBufferLength);
 | 
					 | 
				
			||||||
                        if(level > bestLevel){
 | 
					 | 
				
			||||||
                            {
 | 
					 | 
				
			||||||
                                threads::MutexLock l(blockIndexLock);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                                auto strOffset = string(&hashBuffer[pubKeyLength], hashBufferLength - pubKeyLength);
 | 
					 | 
				
			||||||
                                bestOffset = stoull(strOffset);
 | 
					 | 
				
			||||||
                                auto got = this->getSecurityLevel();
 | 
					 | 
				
			||||||
                                if(got >= level) {
 | 
					 | 
				
			||||||
                                    cout << "Already got bedder level! (" << got << ")" << endl;
 | 
					 | 
				
			||||||
                                    bestLevel = got;
 | 
					 | 
				
			||||||
                                    continue;
 | 
					 | 
				
			||||||
                                }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                                if(verbose) cout << "Improved -> " << level << "/" << target << " [" << strOffset << "]" << endl;
 | 
					 | 
				
			||||||
                                this->lastCheckedOffset = bestOffset;
 | 
					 | 
				
			||||||
                                this->keyOffset = bestOffset;
 | 
					 | 
				
			||||||
                                bestLevel = level;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                                if(bestLevel >= target){
 | 
					 | 
				
			||||||
                                    cout << "Done! (" << bestLevel << ")" << endl;
 | 
					 | 
				
			||||||
                                    *activeDigging = false;
 | 
					 | 
				
			||||||
                                }
 | 
					 | 
				
			||||||
                            }
 | 
					 | 
				
			||||||
                        }
 | 
					 | 
				
			||||||
                        increaseNumBuffer(hashBuffer, pubKeyLength + 1, &hashBufferLength);
 | 
					 | 
				
			||||||
                    }
 | 
					 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
            });
 | 
					 | 
				
			||||||
            thread->name("IdentityHashDigger #" + to_string(threadId));
 | 
					 | 
				
			||||||
            threads.push_back(thread);
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        if(verbose){
 | 
					 | 
				
			||||||
            thread = new threads::Thread([&](){
 | 
					 | 
				
			||||||
                auto lastIndex = currentBlockIndex;
 | 
					 | 
				
			||||||
                while(*activeDigging){
 | 
					 | 
				
			||||||
                    for(int count = 0; count < 1000 && *activeDigging; count++)
 | 
					 | 
				
			||||||
                        usleep(1000);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                    blockIndexLock.lock();
 | 
					 | 
				
			||||||
                    cout << "Current level = " << this->getSecurityLevel() << " at " << this->keyOffset << endl;
 | 
					 | 
				
			||||||
                    cout << "Current offset index: " << currentBlockIndex << " block size: " << nblockSize << endl;
 | 
					 | 
				
			||||||
                    cout << "speed: " << (currentBlockIndex - lastIndex) / 1000 / 1000.f << " Mio. attemps/sec" << endl;
 | 
					 | 
				
			||||||
                    lastIndex = currentBlockIndex;
 | 
					 | 
				
			||||||
                    blockIndexLock.unlock();
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
            });
 | 
					 | 
				
			||||||
            thread->name("Status printer");
 | 
					 | 
				
			||||||
            threads.push_back(thread);
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        for(auto elm : threads){
 | 
					 | 
				
			||||||
            if(elm->state() == threads::ThreadState::RUNNING)
 | 
					 | 
				
			||||||
                elm->join();
 | 
					 | 
				
			||||||
            delete elm;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        return true;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
@ -1,196 +0,0 @@
 | 
				
			|||||||
/*
 | 
					 | 
				
			||||||
 *
 | 
					 | 
				
			||||||
 * TinySHA1 - a header only implementation of the SHA1 algorithm in C++. Based
 | 
					 | 
				
			||||||
 * on the implementation in boost::uuid::details.
 | 
					 | 
				
			||||||
 *
 | 
					 | 
				
			||||||
 * SHA1 Wikipedia Page: http://en.wikipedia.org/wiki/SHA-1
 | 
					 | 
				
			||||||
 *
 | 
					 | 
				
			||||||
 * Copyright (c) 2012-22 SAURAV MOHAPATRA <mohaps@gmail.com>
 | 
					 | 
				
			||||||
 *
 | 
					 | 
				
			||||||
 * Permission to use, copy, modify, and distribute this software for any
 | 
					 | 
				
			||||||
 * purpose with or without fee is hereby granted, provided that the above
 | 
					 | 
				
			||||||
 * copyright notice and this permission notice appear in all copies.
 | 
					 | 
				
			||||||
 *
 | 
					 | 
				
			||||||
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 | 
					 | 
				
			||||||
 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 | 
					 | 
				
			||||||
 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
 | 
					 | 
				
			||||||
 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 | 
					 | 
				
			||||||
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
 | 
					 | 
				
			||||||
 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
 | 
					 | 
				
			||||||
 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
#ifndef _TINY_SHA1_HPP_
 | 
					 | 
				
			||||||
#define _TINY_SHA1_HPP_
 | 
					 | 
				
			||||||
#include <cstdio>
 | 
					 | 
				
			||||||
#include <cstdlib>
 | 
					 | 
				
			||||||
#include <cstring>
 | 
					 | 
				
			||||||
#include <stdint.h>
 | 
					 | 
				
			||||||
namespace sha1
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    class SHA1
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        public:
 | 
					 | 
				
			||||||
            typedef uint32_t digest32_t[5];
 | 
					 | 
				
			||||||
            typedef uint8_t digest8_t[20];
 | 
					 | 
				
			||||||
            inline static uint32_t LeftRotate(uint32_t value, size_t count) {
 | 
					 | 
				
			||||||
                return (value << count) ^ (value >> (32-count));
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
            SHA1(){ reset(); }
 | 
					 | 
				
			||||||
            virtual ~SHA1() {}
 | 
					 | 
				
			||||||
            SHA1(const SHA1& s) { *this = s; }
 | 
					 | 
				
			||||||
            const SHA1& operator = (const SHA1& s) {
 | 
					 | 
				
			||||||
                memcpy(m_digest, s.m_digest, 5 * sizeof(uint32_t));
 | 
					 | 
				
			||||||
                memcpy(m_block, s.m_block, 64);
 | 
					 | 
				
			||||||
                m_blockByteIndex = s.m_blockByteIndex;
 | 
					 | 
				
			||||||
                m_byteCount = s.m_byteCount;
 | 
					 | 
				
			||||||
                return *this;
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
            SHA1& reset() {
 | 
					 | 
				
			||||||
                m_digest[0] = 0x67452301;
 | 
					 | 
				
			||||||
                m_digest[1] = 0xEFCDAB89;
 | 
					 | 
				
			||||||
                m_digest[2] = 0x98BADCFE;
 | 
					 | 
				
			||||||
                m_digest[3] = 0x10325476;
 | 
					 | 
				
			||||||
                m_digest[4] = 0xC3D2E1F0;
 | 
					 | 
				
			||||||
                m_blockByteIndex = 0;
 | 
					 | 
				
			||||||
                m_byteCount = 0;
 | 
					 | 
				
			||||||
                return *this;
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
            SHA1& processByte(uint8_t octet) {
 | 
					 | 
				
			||||||
                this->m_block[this->m_blockByteIndex++] = octet;
 | 
					 | 
				
			||||||
                ++this->m_byteCount;
 | 
					 | 
				
			||||||
                if(m_blockByteIndex == 64) {
 | 
					 | 
				
			||||||
                    this->m_blockByteIndex = 0;
 | 
					 | 
				
			||||||
                    processBlock();
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
                return *this;
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
            SHA1& processBlock(const void* const start, const void* const end) {
 | 
					 | 
				
			||||||
                const uint8_t* begin = static_cast<const uint8_t*>(start);
 | 
					 | 
				
			||||||
                const uint8_t* finish = static_cast<const uint8_t*>(end);
 | 
					 | 
				
			||||||
                while(begin != finish) {
 | 
					 | 
				
			||||||
                    processByte(*begin);
 | 
					 | 
				
			||||||
                    begin++;
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
                return *this;
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
            SHA1& processBytes(const void* const data, size_t len) {
 | 
					 | 
				
			||||||
                const uint8_t* block = static_cast<const uint8_t*>(data);
 | 
					 | 
				
			||||||
                processBlock(block, block + len);
 | 
					 | 
				
			||||||
                return *this;
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
            const uint32_t* getDigest(digest32_t digest) {
 | 
					 | 
				
			||||||
                size_t bitCount = this->m_byteCount * 8;
 | 
					 | 
				
			||||||
                processByte(0x80);
 | 
					 | 
				
			||||||
                if (this->m_blockByteIndex > 56) {
 | 
					 | 
				
			||||||
                    while (m_blockByteIndex != 0) {
 | 
					 | 
				
			||||||
                        processByte(0);
 | 
					 | 
				
			||||||
                    }
 | 
					 | 
				
			||||||
                    while (m_blockByteIndex < 56) {
 | 
					 | 
				
			||||||
                        processByte(0);
 | 
					 | 
				
			||||||
                    }
 | 
					 | 
				
			||||||
                } else {
 | 
					 | 
				
			||||||
                    while (m_blockByteIndex < 56) {
 | 
					 | 
				
			||||||
                        processByte(0);
 | 
					 | 
				
			||||||
                    }
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
                processByte(0);
 | 
					 | 
				
			||||||
                processByte(0);
 | 
					 | 
				
			||||||
                processByte(0);
 | 
					 | 
				
			||||||
                processByte(0);
 | 
					 | 
				
			||||||
                processByte( static_cast<unsigned char>((bitCount>>24) & 0xFF));
 | 
					 | 
				
			||||||
                processByte( static_cast<unsigned char>((bitCount>>16) & 0xFF));
 | 
					 | 
				
			||||||
                processByte( static_cast<unsigned char>((bitCount>>8 ) & 0xFF));
 | 
					 | 
				
			||||||
                processByte( static_cast<unsigned char>((bitCount)     & 0xFF));
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                memcpy(digest, m_digest, 5 * sizeof(uint32_t));
 | 
					 | 
				
			||||||
                return digest;
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
            const uint8_t* getDigestBytes(digest8_t digest) {
 | 
					 | 
				
			||||||
                digest32_t d32;
 | 
					 | 
				
			||||||
                getDigest(d32);
 | 
					 | 
				
			||||||
                size_t di = 0;
 | 
					 | 
				
			||||||
                digest[di++] = ((d32[0] >> 24) & 0xFF);
 | 
					 | 
				
			||||||
                digest[di++] = ((d32[0] >> 16) & 0xFF);
 | 
					 | 
				
			||||||
                digest[di++] = ((d32[0] >> 8) & 0xFF);
 | 
					 | 
				
			||||||
                digest[di++] = ((d32[0]) & 0xFF);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                digest[di++] = ((d32[1] >> 24) & 0xFF);
 | 
					 | 
				
			||||||
                digest[di++] = ((d32[1] >> 16) & 0xFF);
 | 
					 | 
				
			||||||
                digest[di++] = ((d32[1] >> 8) & 0xFF);
 | 
					 | 
				
			||||||
                digest[di++] = ((d32[1]) & 0xFF);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                digest[di++] = ((d32[2] >> 24) & 0xFF);
 | 
					 | 
				
			||||||
                digest[di++] = ((d32[2] >> 16) & 0xFF);
 | 
					 | 
				
			||||||
                digest[di++] = ((d32[2] >> 8) & 0xFF);
 | 
					 | 
				
			||||||
                digest[di++] = ((d32[2]) & 0xFF);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                digest[di++] = ((d32[3] >> 24) & 0xFF);
 | 
					 | 
				
			||||||
                digest[di++] = ((d32[3] >> 16) & 0xFF);
 | 
					 | 
				
			||||||
                digest[di++] = ((d32[3] >> 8) & 0xFF);
 | 
					 | 
				
			||||||
                digest[di++] = ((d32[3]) & 0xFF);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                digest[di++] = ((d32[4] >> 24) & 0xFF);
 | 
					 | 
				
			||||||
                digest[di++] = ((d32[4] >> 16) & 0xFF);
 | 
					 | 
				
			||||||
                digest[di++] = ((d32[4] >> 8) & 0xFF);
 | 
					 | 
				
			||||||
                digest[di++] = ((d32[4]) & 0xFF);
 | 
					 | 
				
			||||||
                return digest;
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        protected:
 | 
					 | 
				
			||||||
            void processBlock() {
 | 
					 | 
				
			||||||
                uint32_t w[80];
 | 
					 | 
				
			||||||
                for (size_t i = 0; i < 16; i++) {
 | 
					 | 
				
			||||||
                    w[i]  = (m_block[i*4 + 0] << 24);
 | 
					 | 
				
			||||||
                    w[i] |= (m_block[i*4 + 1] << 16);
 | 
					 | 
				
			||||||
                    w[i] |= (m_block[i*4 + 2] << 8);
 | 
					 | 
				
			||||||
                    w[i] |= (m_block[i*4 + 3]);
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
                for (size_t i = 16; i < 80; i++) {
 | 
					 | 
				
			||||||
                    w[i] = LeftRotate((w[i-3] ^ w[i-8] ^ w[i-14] ^ w[i-16]), 1);
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                uint32_t a = m_digest[0];
 | 
					 | 
				
			||||||
                uint32_t b = m_digest[1];
 | 
					 | 
				
			||||||
                uint32_t c = m_digest[2];
 | 
					 | 
				
			||||||
                uint32_t d = m_digest[3];
 | 
					 | 
				
			||||||
                uint32_t e = m_digest[4];
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                for (std::size_t i=0; i<80; ++i) {
 | 
					 | 
				
			||||||
                    uint32_t f = 0;
 | 
					 | 
				
			||||||
                    uint32_t k = 0;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                    if (i<20) {
 | 
					 | 
				
			||||||
                        f = (b & c) | (~b & d);
 | 
					 | 
				
			||||||
                        k = 0x5A827999;
 | 
					 | 
				
			||||||
                    } else if (i<40) {
 | 
					 | 
				
			||||||
                        f = b ^ c ^ d;
 | 
					 | 
				
			||||||
                        k = 0x6ED9EBA1;
 | 
					 | 
				
			||||||
                    } else if (i<60) {
 | 
					 | 
				
			||||||
                        f = (b & c) | (b & d) | (c & d);
 | 
					 | 
				
			||||||
                        k = 0x8F1BBCDC;
 | 
					 | 
				
			||||||
                    } else {
 | 
					 | 
				
			||||||
                        f = b ^ c ^ d;
 | 
					 | 
				
			||||||
                        k = 0xCA62C1D6;
 | 
					 | 
				
			||||||
                    }
 | 
					 | 
				
			||||||
                    uint32_t temp = LeftRotate(a, 5) + f + e + k + w[i];
 | 
					 | 
				
			||||||
                    e = d;
 | 
					 | 
				
			||||||
                    d = c;
 | 
					 | 
				
			||||||
                    c = LeftRotate(b, 30);
 | 
					 | 
				
			||||||
                    b = a;
 | 
					 | 
				
			||||||
                    a = temp;
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                m_digest[0] += a;
 | 
					 | 
				
			||||||
                m_digest[1] += b;
 | 
					 | 
				
			||||||
                m_digest[2] += c;
 | 
					 | 
				
			||||||
                m_digest[3] += d;
 | 
					 | 
				
			||||||
                m_digest[4] += e;
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
        private:
 | 
					 | 
				
			||||||
            digest32_t m_digest;
 | 
					 | 
				
			||||||
            uint8_t m_block[64];
 | 
					 | 
				
			||||||
            size_t m_blockByteIndex;
 | 
					 | 
				
			||||||
            size_t m_byteCount;
 | 
					 | 
				
			||||||
    };
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
@ -1,454 +0,0 @@
 | 
				
			|||||||
//
 | 
					 | 
				
			||||||
// Created by wolverindev on 07.10.17.
 | 
					 | 
				
			||||||
//
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#include <log/LogUtils.h>
 | 
					 | 
				
			||||||
#include "Connection.h"
 | 
					 | 
				
			||||||
#include "misc/base64.h"
 | 
					 | 
				
			||||||
#include <misc/endianness.h>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#include <arpa/inet.h>
 | 
					 | 
				
			||||||
#include <poll.h>
 | 
					 | 
				
			||||||
#include <openssl/sha.h>
 | 
					 | 
				
			||||||
#include <bitset>
 | 
					 | 
				
			||||||
#include <protocol/Packet.h>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
using namespace std;
 | 
					 | 
				
			||||||
using namespace ts;
 | 
					 | 
				
			||||||
using namespace ts::connection;
 | 
					 | 
				
			||||||
using namespace ts::protocol;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
ServerConnection::ServerConnection() {
 | 
					 | 
				
			||||||
    cryptionHandler = new CryptionHandler();
 | 
					 | 
				
			||||||
    cryptionHandler->reset();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	compressionHandler = new CompressionHandler();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    readQueue = (buffer::SortedBufferQueue<ServerPacket> **) malloc(16 * sizeof(void*));
 | 
					 | 
				
			||||||
    for(int i = 0; i < 16; i++) {
 | 
					 | 
				
			||||||
        auto type = ts::protocol::PacketTypeInfo::fromid(i);
 | 
					 | 
				
			||||||
        if(type != PacketTypeInfo::Undefined){
 | 
					 | 
				
			||||||
            readQueue[i] = new buffer::SortedBufferQueue<ServerPacket>(ts::protocol::PacketTypeInfo::fromid(i), PacketTypeInfo::Command != type); //Ignore command low
 | 
					 | 
				
			||||||
        } else {
 | 
					 | 
				
			||||||
            readQueue[i] = nullptr;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
ServerConnection::~ServerConnection() {
 | 
					 | 
				
			||||||
    for(int i = 0; i < 16; i++)
 | 
					 | 
				
			||||||
        if(readQueue[i])
 | 
					 | 
				
			||||||
            delete readQueue[i];
 | 
					 | 
				
			||||||
    free(readQueue);
 | 
					 | 
				
			||||||
	this->rwThread->join();
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static int sourcePort = 50000;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void ServerConnection::disconnect() {
 | 
					 | 
				
			||||||
	//this->rwThread->cancel();
 | 
					 | 
				
			||||||
	//this->handleThread->cancel();
 | 
					 | 
				
			||||||
	this->connected = false;
 | 
					 | 
				
			||||||
	if(this->socket) this->socket->close();
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
bool ServerConnection::connect(std::string host, std::string port, Identity *identity) {
 | 
					 | 
				
			||||||
    this->clientIdentity = identity;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    memset(&remoteAddress, 0, sizeof(remoteAddress));
 | 
					 | 
				
			||||||
    remoteAddress.sin_family = AF_INET;
 | 
					 | 
				
			||||||
    remoteAddress.sin_port = htons((uint16_t) std::stoi(port));
 | 
					 | 
				
			||||||
    remoteAddress.sin_addr.s_addr = inet_addr(host.c_str());
 | 
					 | 
				
			||||||
#ifdef NoQt
 | 
					 | 
				
			||||||
    /*
 | 
					 | 
				
			||||||
    this->socketfd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
 | 
					 | 
				
			||||||
    int allow = 1;
 | 
					 | 
				
			||||||
    setsockopt(this->socketfd, SOL_SOCKET, SO_REUSEADDR, &allow, sizeof(int));
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    memset(&localAddress, 0, sizeof(localAddress));
 | 
					 | 
				
			||||||
    localAddress.sin_family = AF_INET;
 | 
					 | 
				
			||||||
    localAddress.sin_addr.s_addr = htonl (INADDR_ANY);
 | 
					 | 
				
			||||||
    localAddress.sin_port = htons (sourcePort++);
 | 
					 | 
				
			||||||
    ::connect(this->socketfd, (const sockaddr *) &remoteHost, sizeof(this->remoteAddress));
 | 
					 | 
				
			||||||
    //bind(this->socketfd, (struct sockaddr *) &localAddress, sizeof(localAddress));
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
     */
 | 
					 | 
				
			||||||
    this->socket = new UdpSocket;
 | 
					 | 
				
			||||||
    if(!this->socket->setup(&remoteAddress)){
 | 
					 | 
				
			||||||
        cerr << "Invalid socket setup" << endl;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
#else
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
    this->rwThread = new threads::Thread(THREAD_SAVE_OPERATIONS, [&]() {
 | 
					 | 
				
			||||||
#ifndef NoQt
 | 
					 | 
				
			||||||
        this->qtSocket = new QUdpSocket();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        QObject::connect(qtSocket,SIGNAL(bytesWritten(qint64)),this,SLOT(bytesWritten(qint64)));
 | 
					 | 
				
			||||||
        QObject::connect(this->qtSocket, SIGNAL(readyRead()), this, SLOT(attempDatagramRead()));
 | 
					 | 
				
			||||||
        this->qtSocket->bind(QHostAddress::Any, 23111);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        this->socketfd = qtSocket->socketDescriptor();
 | 
					 | 
				
			||||||
        cout << "Sock fd: " << this->socketfd << endl;
 | 
					 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
        /*
 | 
					 | 
				
			||||||
        auto cthread = QThread::currentThread();
 | 
					 | 
				
			||||||
        cout << "ex" << endl;
 | 
					 | 
				
			||||||
        runOnThread(qtSocket->thread(), [&](){
 | 
					 | 
				
			||||||
            cout << "try" << endl;
 | 
					 | 
				
			||||||
            qtSocket->moveToThread(cthread);
 | 
					 | 
				
			||||||
            cout << "Moved" << endl;
 | 
					 | 
				
			||||||
        });
 | 
					 | 
				
			||||||
        cout << "Start rw" << endl;
 | 
					 | 
				
			||||||
         */
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        this->rwExecutor();
 | 
					 | 
				
			||||||
    });
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	/*
 | 
					 | 
				
			||||||
    this->handleThread = new threads::Thread([&]() {
 | 
					 | 
				
			||||||
        this->handleExecutor();
 | 
					 | 
				
			||||||
    });
 | 
					 | 
				
			||||||
    */
 | 
					 | 
				
			||||||
    return true;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#ifndef NoQt
 | 
					 | 
				
			||||||
void ServerConnection::bytesWritten(qint64 b) {
 | 
					 | 
				
			||||||
    cout << "written " << b << endl;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void ServerConnection::attempDatagramRead() {
 | 
					 | 
				
			||||||
    cout << "Data " << endl;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
//this->socket->socketDescriptor()
 | 
					 | 
				
			||||||
void ServerConnection::rwExecutor() {
 | 
					 | 
				
			||||||
    pollfd pollData = {this->socket->getSocketDescriptor(), POLLRDHUP | POLLIN | POLLOUT, 0};
 | 
					 | 
				
			||||||
    buffer::RawBuffer readBuffer(512);
 | 
					 | 
				
			||||||
    std::shared_ptr<protocol::ServerPacket> readedPacket;
 | 
					 | 
				
			||||||
    while (socket->getSocketDescriptor() > 0 && this->connected) {
 | 
					 | 
				
			||||||
        int rfds = poll(&pollData, 1, -1);
 | 
					 | 
				
			||||||
	    bool select = false;
 | 
					 | 
				
			||||||
	    if(rfds == 0) {
 | 
					 | 
				
			||||||
		    usleep(5 * 1000);;
 | 
					 | 
				
			||||||
		    continue;
 | 
					 | 
				
			||||||
	    } else if(rfds < 0) {
 | 
					 | 
				
			||||||
		    break;
 | 
					 | 
				
			||||||
	    }
 | 
					 | 
				
			||||||
        if (pollData.revents & POLLRDHUP || pollData.revents & POLLHUP) {
 | 
					 | 
				
			||||||
	        select = 1;
 | 
					 | 
				
			||||||
            cerr << "Connection hang up!" << endl;
 | 
					 | 
				
			||||||
            return;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        if (pollData.revents & POLLIN) {
 | 
					 | 
				
			||||||
	        select = 1;
 | 
					 | 
				
			||||||
            ssize_t readedBytes = -1;
 | 
					 | 
				
			||||||
#ifdef NoQt
 | 
					 | 
				
			||||||
            readedBytes = socket->read(readBuffer.buffer, readBuffer.length);
 | 
					 | 
				
			||||||
	#ifdef DEBUG
 | 
					 | 
				
			||||||
	        cout << "Read bytes (" << readedBytes << ")" << endl;
 | 
					 | 
				
			||||||
	#endif
 | 
					 | 
				
			||||||
#else
 | 
					 | 
				
			||||||
            QHostAddress senderAddr;
 | 
					 | 
				
			||||||
            quint16 senderPort;
 | 
					 | 
				
			||||||
            readedBytes = this->qtSocket->readDatagram(readBuffer.buffer, readBuffer.length, &senderAddr, &senderPort);
 | 
					 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
            if (readedBytes < 0) {
 | 
					 | 
				
			||||||
                cout << "fatal read error: " << errno << "/" << strerror(errno) << endl;
 | 
					 | 
				
			||||||
                return;
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            readedPacket = std::make_shared<ServerPacket>(pipes::buffer_view(readBuffer.buffer, readedBytes));
 | 
					 | 
				
			||||||
            if(!preProgressPacket(readedPacket)){
 | 
					 | 
				
			||||||
                cerr << "Invalid packet preprocess!" << endl;
 | 
					 | 
				
			||||||
                readedPacket = nullptr;
 | 
					 | 
				
			||||||
                goto exitRead;
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            if(readedPacket->type().type() < 0 || readedPacket->type().type() > 16){
 | 
					 | 
				
			||||||
                cerr << "Invalid packet id!" << endl;
 | 
					 | 
				
			||||||
                readedPacket = nullptr;
 | 
					 | 
				
			||||||
                goto exitRead;
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
            //Deserelize packet
 | 
					 | 
				
			||||||
            this->bufferQueueLock.lock();
 | 
					 | 
				
			||||||
            if(!this->readQueue[readedPacket->type().type()]->push_pack(readedPacket)){
 | 
					 | 
				
			||||||
                //TODO error handling
 | 
					 | 
				
			||||||
                cout << "pkId: " << be2le16((char*) readedPacket->data().data_ptr()) << " -> " << readedPacket->type().name() << endl;
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
            this->bufferQueueLock.unlock();
 | 
					 | 
				
			||||||
	        while(this->handleNextPacket());
 | 
					 | 
				
			||||||
            exitRead:;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        if (pollData.revents & POLLOUT) {
 | 
					 | 
				
			||||||
            this->bufferQueueLock.lock();
 | 
					 | 
				
			||||||
            if (!this->writeQueue.empty()) {
 | 
					 | 
				
			||||||
	            select = 1;
 | 
					 | 
				
			||||||
                buffer::RawBuffer buffer = this->writeQueue.front();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#ifdef NoQt
 | 
					 | 
				
			||||||
                auto res = this->socket->write(buffer.buffer, buffer.length);
 | 
					 | 
				
			||||||
                if (res == -1) {
 | 
					 | 
				
			||||||
                    cout << "having write error: " << errno << "/" << strerror(errno) << " -> " << buffer.length << endl;
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
                //cout << string() + "Write: " + PacketType::fromid(buffer.type()).name() << endl;
 | 
					 | 
				
			||||||
#else
 | 
					 | 
				
			||||||
                this->qtSocket->writeDatagram(buffer.buffer, buffer.length, QHostAddress("localhost"), htons(this->remoteAddress.sin_port));
 | 
					 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                /*
 | 
					 | 
				
			||||||
                if(!PacketTypeInfo::fromid(buffer.type()).requireAcknowledge()){ //Than we need a ack!
 | 
					 | 
				
			||||||
                    //Wait for acknowlage
 | 
					 | 
				
			||||||
                    this->acknowlageQueueLock.lock();
 | 
					 | 
				
			||||||
                    this->acknowlageQueue.push_back(buffer);
 | 
					 | 
				
			||||||
                    this->acknowlageQueueLock.unlock();
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
                 */
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                this->writeQueue.pop_front();
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
            this->bufferQueueLock.unlock();
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
	    if (!select) {
 | 
					 | 
				
			||||||
		    usleep(5 * 10000);
 | 
					 | 
				
			||||||
		    continue;
 | 
					 | 
				
			||||||
	    }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    cerr << "rw loop broken!" << endl;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
bool ServerConnection::preProgressPacket(std::shared_ptr<protocol::ServerPacket> packet){
 | 
					 | 
				
			||||||
	packet->setEncrypted(!packet->hasFlag(PacketFlag::Unencrypted));
 | 
					 | 
				
			||||||
    packet->setCompressed(packet->hasFlag(PacketFlag::Compressed));
 | 
					 | 
				
			||||||
    packet->setFragmentedEntry(packet->hasFlag(PacketFlag::Fragmented));
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    if(packet->type() == PacketTypeInfo::Init1){
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    if (packet->isEncrypted()) {
 | 
					 | 
				
			||||||
        string error = "success";
 | 
					 | 
				
			||||||
        if (!cryptionHandler->progressPacketIn(packet.get(), error, false)) {
 | 
					 | 
				
			||||||
            cerr << "Cant decript packet! Message: " << error << endl;
 | 
					 | 
				
			||||||
            cerr << "Dropping it!" << endl;
 | 
					 | 
				
			||||||
            return false;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#ifdef DEBUG
 | 
					 | 
				
			||||||
    cout << "[IN] Packet type -> " << packet->type().name() << " flags " << packet->flags() << " Length: " << packet->data().length() << endl;
 | 
					 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
    if(packet->type() == PacketTypeInfo::Command || packet->type() == PacketTypeInfo::CommandLow){ //needs an acknowledge
 | 
					 | 
				
			||||||
	    sendAcknowledge(packet->packetId(), packet->type() == PacketTypeInfo::CommandLow);
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    return true;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
//TODO right packet recive order!
 | 
					 | 
				
			||||||
void ServerConnection::handleExecutor() {
 | 
					 | 
				
			||||||
    shared_ptr<protocol::ServerPacket> packet = nullptr;
 | 
					 | 
				
			||||||
    string error = "success";
 | 
					 | 
				
			||||||
    while(this->connected){
 | 
					 | 
				
			||||||
        while(this->handleNextPacket());
 | 
					 | 
				
			||||||
	    usleep(10 * 1000);
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
bool ServerConnection::handleNextPacket() {
 | 
					 | 
				
			||||||
	shared_ptr<protocol::ServerPacket> packet = nullptr;
 | 
					 | 
				
			||||||
	string error = "success";
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if(this->autoHandle){
 | 
					 | 
				
			||||||
		handleQueueLock.lock();
 | 
					 | 
				
			||||||
		if(!this->handleQueue.empty()) {
 | 
					 | 
				
			||||||
			packet = this->handleQueue.front();
 | 
					 | 
				
			||||||
			this->handleQueue.pop_front();
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		handleQueueLock.unlock();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		if(packet){
 | 
					 | 
				
			||||||
				if(packet->type() == PacketTypeInfo::Ack || packet->type() == PacketTypeInfo::AckLow){
 | 
					 | 
				
			||||||
					handlePacketAck(packet);
 | 
					 | 
				
			||||||
				} else if(packet->type() == PacketTypeInfo::Command || packet->type() == PacketTypeInfo::CommandLow){
 | 
					 | 
				
			||||||
					handlePacketCommand(packet);
 | 
					 | 
				
			||||||
				} else if(packet->type() == PacketTypeInfo::Ping || packet->type() == PacketTypeInfo::Pong){
 | 
					 | 
				
			||||||
					handlePacketPing(packet);
 | 
					 | 
				
			||||||
				} else if(packet->type() == PacketTypeInfo::Voice || packet->type() == PacketTypeInfo::VoiceWhisper){
 | 
					 | 
				
			||||||
					handlePacketVoice(packet);
 | 
					 | 
				
			||||||
				}
 | 
					 | 
				
			||||||
			return true;
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	for(int index = 0; index < 16; index++){
 | 
					 | 
				
			||||||
		if(this->readQueue[index]) {
 | 
					 | 
				
			||||||
			if(this->readQueue[index]->available() > 0){
 | 
					 | 
				
			||||||
				auto npacket = this->readQueue[index]->peekNext(0);
 | 
					 | 
				
			||||||
				packet = make_shared<ServerPacket>(npacket->buffer());
 | 
					 | 
				
			||||||
				packet->setEncrypted(npacket->isEncrypted());
 | 
					 | 
				
			||||||
				packet->setCompressed(npacket->isCompressed());
 | 
					 | 
				
			||||||
				packet->setFragmentedEntry(npacket->isFragmentEntry());
 | 
					 | 
				
			||||||
				break;
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	if(!packet) return false;
 | 
					 | 
				
			||||||
	if(packet->isFragmentEntry()){
 | 
					 | 
				
			||||||
		packet->setFragmentedEntry(false);
 | 
					 | 
				
			||||||
		int deltaPacketIndex = 0;
 | 
					 | 
				
			||||||
		while(this->connected){
 | 
					 | 
				
			||||||
			std::shared_ptr<protocol::ServerPacket> nextElm = this->readQueue[packet->type().type()]->peekNext(++deltaPacketIndex);
 | 
					 | 
				
			||||||
			if(!nextElm)
 | 
					 | 
				
			||||||
				return false;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
			if(!nextElm) {
 | 
					 | 
				
			||||||
				cerr << "Dropped fragment?" << endl;
 | 
					 | 
				
			||||||
				packet = nullptr;
 | 
					 | 
				
			||||||
				break;
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
			packet->append_data({nextElm->data()});
 | 
					 | 
				
			||||||
			if(nextElm->hasFlag(protocol::PacketFlag::Fragmented)) break; //Tail end
 | 
					 | 
				
			||||||
			nextElm = nullptr;
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		this->readQueue[packet->type().type()]->pop_packets(deltaPacketIndex);
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	this->readQueue[packet->type().type()]->pop_packets(1);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if(packet->type() != PacketTypeInfo::Init1 && !this->compressionHandler->progressPacketIn(packet.get(), error)){
 | 
					 | 
				
			||||||
		cerr << "Cant decompress packet! (" << error << ")" << endl;
 | 
					 | 
				
			||||||
		packet = nullptr;
 | 
					 | 
				
			||||||
		return true;
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#if defined(DEBUG_PACKET_LOG)
 | 
					 | 
				
			||||||
	cout << "Parsed packet " << packet->type().name() << " with id " << packet->packetId() << ". Data:" << endl;
 | 
					 | 
				
			||||||
	hexDump((void *) packet->data().data_ptr(), packet->data().length(), 16, 8, [](std::string line) {
 | 
					 | 
				
			||||||
		cout << "[IN] " << line << endl;
 | 
					 | 
				
			||||||
	});
 | 
					 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
	handleQueueLock.lock();
 | 
					 | 
				
			||||||
	this->handleQueue.push_back(packet);
 | 
					 | 
				
			||||||
	handleQueueLock.unlock();
 | 
					 | 
				
			||||||
	return true;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
using namespace std::chrono;
 | 
					 | 
				
			||||||
std::shared_ptr<protocol::ServerPacket> ServerConnection::readNextPacket(bool block) {
 | 
					 | 
				
			||||||
    auto start = system_clock::now();
 | 
					 | 
				
			||||||
    attempGet:
 | 
					 | 
				
			||||||
    if(system_clock::now() - start > seconds(5)) return nullptr;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    this->handleQueueLock.lock();
 | 
					 | 
				
			||||||
    if (this->handleQueue.empty()) {
 | 
					 | 
				
			||||||
        this->handleQueueLock.unlock();
 | 
					 | 
				
			||||||
        if (!block) return nullptr;
 | 
					 | 
				
			||||||
	    usleep(5 * 1000);
 | 
					 | 
				
			||||||
	    goto attempGet;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    std::shared_ptr<protocol::ServerPacket> packet = std::move(this->handleQueue.front());
 | 
					 | 
				
			||||||
    this->handleQueue.pop_front();
 | 
					 | 
				
			||||||
    this->handleQueueLock.unlock();
 | 
					 | 
				
			||||||
    return packet;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
bool ServerConnection::setupSharedSecret(std::string alpha, std::string beta, std::string sharedKey, std::string &error) {
 | 
					 | 
				
			||||||
    return this->cryptionHandler->setupSharedSecret(alpha, beta, sharedKey, error);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
//Packet splitting not working correctly! (On clientinit dosnt wait for the second)
 | 
					 | 
				
			||||||
void ServerConnection::sendPacket(ts::protocol::ClientPacket &packet) {
 | 
					 | 
				
			||||||
    int maxDataLength = 500 - packet.header().length();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    if(packet.data().length() > maxDataLength){
 | 
					 | 
				
			||||||
        string error;
 | 
					 | 
				
			||||||
/*
 | 
					 | 
				
			||||||
		packet.enableFlag(PacketFlag::Compressed);
 | 
					 | 
				
			||||||
        if(!this->compressionHandler->progressPacketOut(&packet, error)){
 | 
					 | 
				
			||||||
            cerr << "Compress error!" << endl;
 | 
					 | 
				
			||||||
            return;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        packet.enableFlag(PacketFlag::Compressed);
 | 
					 | 
				
			||||||
*/
 | 
					 | 
				
			||||||
        if(packet.data().length() > maxDataLength){
 | 
					 | 
				
			||||||
	        std::vector<shared_ptr<ClientPacket>> siblings;
 | 
					 | 
				
			||||||
	        siblings.reserve(8);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	        { //Split packets
 | 
					 | 
				
			||||||
		        auto buffer = packet.data();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		        const auto max_length = packet.type().max_length();
 | 
					 | 
				
			||||||
		        while(buffer.length() > max_length * 2) {
 | 
					 | 
				
			||||||
			        siblings.push_back(make_shared<ClientPacket>(packet.type(), buffer.view(0, max_length)));
 | 
					 | 
				
			||||||
			        buffer = buffer.range(max_length);
 | 
					 | 
				
			||||||
		        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		        if(buffer.length() > max_length) { //Divide rest by 2
 | 
					 | 
				
			||||||
			        siblings.push_back(make_shared<ClientPacket>(packet.type(), buffer.view(0, buffer.length() / 2)));
 | 
					 | 
				
			||||||
			        buffer = buffer.range(buffer.length() / 2);
 | 
					 | 
				
			||||||
		        }
 | 
					 | 
				
			||||||
		        siblings.push_back(make_shared<ClientPacket>(packet.type(), buffer));
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		        for(const auto& frag : siblings) {
 | 
					 | 
				
			||||||
			        frag->setFragmentedEntry(true);
 | 
					 | 
				
			||||||
			        frag->enableFlag(PacketFlag::NewProtocol);
 | 
					 | 
				
			||||||
		        }
 | 
					 | 
				
			||||||
	        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	        for(const auto& entry : siblings)
 | 
					 | 
				
			||||||
	        	this->sendPacket(*entry);
 | 
					 | 
				
			||||||
	        return;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if(!packet.memory_state.id_branded)
 | 
					 | 
				
			||||||
	    packet.applyPacketId(idManager);
 | 
					 | 
				
			||||||
    packet.clientId(this->clientId);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    string error = "success";
 | 
					 | 
				
			||||||
    if (!this->cryptionHandler->progressPacketOut(&packet, error, false)) {
 | 
					 | 
				
			||||||
        cerr << "Invalid crypt -> " << error << endl;
 | 
					 | 
				
			||||||
        return;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    buffer::RawBuffer buffer(packet.buffer().length());
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    memcpy(&buffer.buffer[0],                                                packet.buffer().data_ptr(), packet.buffer().length());
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    this->bufferQueueLock.lock();
 | 
					 | 
				
			||||||
    this->writeQueue.push_back(buffer);
 | 
					 | 
				
			||||||
#if defined(DEBUG_PACKET_LOG)
 | 
					 | 
				
			||||||
    cout << "Send packet " << packet.type().name() << " fragmented -> " << packet.isFragmentEntry() << " length " << packet.data().length() << " flags " << packet.flags() << " ID: " << packet.packetId() << endl;
 | 
					 | 
				
			||||||
	hexDump(buffer.buffer, buffer.length, buffer.length, buffer.length);
 | 
					 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
    this->bufferQueueLock.unlock();
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void ServerConnection::sendCommand(ts::Command command, bool low) {
 | 
					 | 
				
			||||||
	auto data = command.build();
 | 
					 | 
				
			||||||
    protocol::ClientPacket pkt(low ? protocol::PacketTypeInfo::CommandLow : protocol::PacketTypeInfo::Command, pipes::buffer_view{(void*) data.data(), data.length()});
 | 
					 | 
				
			||||||
#ifdef DEBUG
 | 
					 | 
				
			||||||
    cout << "[Client -> Server][" << pkt.type().name() << "] " << pkt.data() << endl;
 | 
					 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
    if(!low) pkt.enableFlag(PacketFlag::NewProtocol);
 | 
					 | 
				
			||||||
    sendPacket(pkt);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void ServerConnection::sendAcknowledge(uint16_t packetId, bool low) {
 | 
					 | 
				
			||||||
	if(breakAck) return;
 | 
					 | 
				
			||||||
    char buffer[2];
 | 
					 | 
				
			||||||
    le2be16(packetId, buffer);
 | 
					 | 
				
			||||||
    protocol::ClientPacket pkt(low ? protocol::PacketTypeInfo::AckLow : protocol::PacketTypeInfo::Ack, pipes::buffer_view(buffer, 2));
 | 
					 | 
				
			||||||
#ifdef DEBUG
 | 
					 | 
				
			||||||
	cout << "Sending packet acknowledge for " << packetId << " (Encrypt: " << encriptAck << ")" << endl;
 | 
					 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
    if(!encriptAck)
 | 
					 | 
				
			||||||
        pkt.enableFlag(PacketFlag::Unencrypted);
 | 
					 | 
				
			||||||
    if(!low) pkt.toggle(protocol::PacketFlag::NewProtocol, true);
 | 
					 | 
				
			||||||
    sendPacket(pkt);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
@ -1,139 +0,0 @@
 | 
				
			|||||||
#pragma once
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#include <ThreadPool/Thread.h>
 | 
					 | 
				
			||||||
#include <ThreadPool/Mutex.h>
 | 
					 | 
				
			||||||
#include <string>
 | 
					 | 
				
			||||||
#include <thread>
 | 
					 | 
				
			||||||
#include <netinet/in.h>
 | 
					 | 
				
			||||||
#include <deque>
 | 
					 | 
				
			||||||
#include <list>
 | 
					 | 
				
			||||||
#include <protocol/Packet.h>
 | 
					 | 
				
			||||||
#include <protocol/buffers.h>
 | 
					 | 
				
			||||||
#include <src/protocol/socket/FilteredUDPSocket.h>
 | 
					 | 
				
			||||||
#include <src/Identity.h>
 | 
					 | 
				
			||||||
#include <protocol/CryptionHandler.h>
 | 
					 | 
				
			||||||
#include <protocol/CompressionHandler.h>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#define NoQt
 | 
					 | 
				
			||||||
#ifndef NoQt
 | 
					 | 
				
			||||||
    #include <QUdpSocket>
 | 
					 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#define DEBUG_PACKET_LOG
 | 
					 | 
				
			||||||
//#define LOG_CMD
 | 
					 | 
				
			||||||
namespace ts {
 | 
					 | 
				
			||||||
    namespace connection {
 | 
					 | 
				
			||||||
        namespace ConnectionState {
 | 
					 | 
				
			||||||
            enum ConnectionState {
 | 
					 | 
				
			||||||
                UNCONNECTED,
 | 
					 | 
				
			||||||
                LLHANDSCHAKE,
 | 
					 | 
				
			||||||
                HANDSCHAKE,
 | 
					 | 
				
			||||||
                CONNECTED,
 | 
					 | 
				
			||||||
                DISCONNECTED
 | 
					 | 
				
			||||||
            };
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        class ServerConnection
 | 
					 | 
				
			||||||
#ifndef NoQt
 | 
					 | 
				
			||||||
: public QObject {
 | 
					 | 
				
			||||||
                Q_OBJECT
 | 
					 | 
				
			||||||
#else
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
            public:
 | 
					 | 
				
			||||||
                ServerConnection();
 | 
					 | 
				
			||||||
                ~ServerConnection();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                bool connect(std::string host, std::string port, Identity* identity);
 | 
					 | 
				
			||||||
			    void disconnect();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                ConnectionState::ConnectionState getConnectionState(){ return cstate; }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                bool handshake(std::string &errorMessage);
 | 
					 | 
				
			||||||
			    bool handshakeNew(Command &cmd, const std::string& alpha, std::string &errorMessage);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                void sendPacket(ts::protocol::ClientPacket& packet);
 | 
					 | 
				
			||||||
                void sendCommand(ts::Command command, bool low = false);
 | 
					 | 
				
			||||||
                void sendAcknowledge(uint16_t packetId, bool low = false);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                std::shared_ptr<protocol::ServerPacket> readNextPacket(bool block = true);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                uint16_t getClientId(){
 | 
					 | 
				
			||||||
                    return this->clientId;
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                void setClientId(uint16_t id){
 | 
					 | 
				
			||||||
                    this->clientId = id;
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#ifndef NoQt
 | 
					 | 
				
			||||||
            public slots:
 | 
					 | 
				
			||||||
                void attempDatagramRead();
 | 
					 | 
				
			||||||
                void bytesWritten(qint64);
 | 
					 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
            private:
 | 
					 | 
				
			||||||
                bool encriptAck = false;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                bool preProgressPacket(std::shared_ptr<protocol::ServerPacket> packet);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                void rwExecutor();
 | 
					 | 
				
			||||||
                void handleExecutor();
 | 
					 | 
				
			||||||
			    bool handleNextPacket();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                bool setupSharedSecret(std::string alpha, std::string beta, std::string sharedKey, std::string& error);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                void handlePacketPing(std::shared_ptr<protocol::ServerPacket> packet);
 | 
					 | 
				
			||||||
                void handlePacketCommand(std::shared_ptr<protocol::ServerPacket> packet);
 | 
					 | 
				
			||||||
                void handlePacketAck(std::shared_ptr<protocol::ServerPacket> packet);
 | 
					 | 
				
			||||||
                void handlePacketVoice(std::shared_ptr<protocol::ServerPacket> packet);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
			    bool connected = true;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                sockaddr_in remoteAddress;
 | 
					 | 
				
			||||||
                sockaddr_in localAddress;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                UdpSocket* socket;
 | 
					 | 
				
			||||||
                threads::Thread* rwThread = nullptr;
 | 
					 | 
				
			||||||
                std::deque<buffer::RawBuffer> writeQueue;
 | 
					 | 
				
			||||||
#ifndef NoQt
 | 
					 | 
				
			||||||
                QUdpSocket* qtSocket = nullptr;
 | 
					 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                threads::Mutex bufferQueueLock;
 | 
					 | 
				
			||||||
                buffer::SortedBufferQueue<protocol::ServerPacket>** readQueue = nullptr;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                //std::deque<RawBuffer> readQueue;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                std::deque<buffer::RawBuffer> acknowlageQueue;
 | 
					 | 
				
			||||||
                threads::Mutex acknowlageQueueLock;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                protocol::PacketIdManager idManager;
 | 
					 | 
				
			||||||
                threads::Thread* handleThread = nullptr;
 | 
					 | 
				
			||||||
                std::list<std::shared_ptr<protocol::ServerPacket>> handleQueue; //Parsed packets
 | 
					 | 
				
			||||||
                threads::Mutex handleQueueLock;
 | 
					 | 
				
			||||||
                bool autoHandle = false;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                ts::connection::CryptionHandler* cryptionHandler = nullptr;
 | 
					 | 
				
			||||||
			    ts::connection::CompressionHandler* compressionHandler = nullptr;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                std::string remoteHost;
 | 
					 | 
				
			||||||
                uint16_t remotePort;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                Identity* clientIdentity;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                ConnectionState::ConnectionState cstate = ConnectionState::UNCONNECTED;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
			    bool breakAck = false;
 | 
					 | 
				
			||||||
                /**
 | 
					 | 
				
			||||||
                 * TS3 Client data
 | 
					 | 
				
			||||||
                 */
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                uint16_t clientId = 0;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                std::deque<ChannelId> channels;
 | 
					 | 
				
			||||||
        };
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
@ -1,361 +0,0 @@
 | 
				
			|||||||
//
 | 
					 | 
				
			||||||
// Created by wolverindev on 08.10.17.
 | 
					 | 
				
			||||||
//
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#include <tommath.h>
 | 
					 | 
				
			||||||
#include <bitset>
 | 
					 | 
				
			||||||
#include <openssl/sha.h>
 | 
					 | 
				
			||||||
#include "Connection.h"
 | 
					 | 
				
			||||||
#include "misc/base64.h"
 | 
					 | 
				
			||||||
#include "misc/endianness.h"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
using namespace std;
 | 
					 | 
				
			||||||
using namespace std::chrono;
 | 
					 | 
				
			||||||
using namespace ts;
 | 
					 | 
				
			||||||
using namespace ts::connection;
 | 
					 | 
				
			||||||
using namespace ts::protocol;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
const int InitVersionLength = 4;
 | 
					 | 
				
			||||||
const uint8_t InitVersion[InitVersionLength] = {0x09, 0x83, 0x8C, 0xCF};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/**
 | 
					 | 
				
			||||||
 * Maybe memset to 0 for security?
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
#define RESET_DATA \
 | 
					 | 
				
			||||||
bufferIndex = 0;   \
 | 
					 | 
				
			||||||
delete pkt;        \
 | 
					 | 
				
			||||||
pkt = nullptr;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
inline ClientPacket *solvePuzzle(shared_ptr<ServerPacket> response, Identity *, std::string &);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
inline std::string toString(mp_int* num){
 | 
					 | 
				
			||||||
    char buffer[2048];
 | 
					 | 
				
			||||||
    memset(buffer, 0, 2048);
 | 
					 | 
				
			||||||
    auto len = mp_todecimal(num, buffer);
 | 
					 | 
				
			||||||
    return string(buffer);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
extern void hexdump(std::ostream& outs, const std::string& s, size_t line_len = 16);
 | 
					 | 
				
			||||||
bool ServerConnection::handshake(std::string &errorMessage) {
 | 
					 | 
				
			||||||
    //setup the init mac
 | 
					 | 
				
			||||||
    /**
 | 
					 | 
				
			||||||
     * Low level
 | 
					 | 
				
			||||||
     */
 | 
					 | 
				
			||||||
    ts::protocol::ClientPacket *pkt;
 | 
					 | 
				
			||||||
    shared_ptr<ServerPacket> response;
 | 
					 | 
				
			||||||
    int maxBufferSize = 512;
 | 
					 | 
				
			||||||
    size_t bufferIndex = 0;
 | 
					 | 
				
			||||||
    uint8_t buffer[maxBufferSize];
 | 
					 | 
				
			||||||
	memset(buffer, 0, maxBufferSize);
 | 
					 | 
				
			||||||
    int err = 0;
 | 
					 | 
				
			||||||
    string error = "success";
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	beginCoocie:
 | 
					 | 
				
			||||||
    memcpy(buffer, InitVersion, InitVersionLength);
 | 
					 | 
				
			||||||
    bufferIndex += InitVersionLength;
 | 
					 | 
				
			||||||
    buffer[bufferIndex++] = 0x00; //Login state
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    auto millis = duration_cast<milliseconds>(system_clock::now().time_since_epoch()).count();
 | 
					 | 
				
			||||||
    memcpy(&buffer[bufferIndex], &millis, 4);
 | 
					 | 
				
			||||||
    bufferIndex += 4;
 | 
					 | 
				
			||||||
    //generate the alpha key
 | 
					 | 
				
			||||||
    for (int i = 0; i < 4; i++) buffer[bufferIndex++] = (uint8_t) std::rand();
 | 
					 | 
				
			||||||
    bufferIndex += 8; //Reserved bytes
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	pkt = new ts::protocol::ClientPacket(ts::protocol::PacketTypeInfo::Init1, pipes::buffer_view((void *) buffer, bufferIndex));
 | 
					 | 
				
			||||||
	pkt->clientId(0);
 | 
					 | 
				
			||||||
	pkt->toggle(ts::protocol::PacketFlag::Unencrypted, true);
 | 
					 | 
				
			||||||
	pkt->applyPacketId(101, 0);
 | 
					 | 
				
			||||||
	this->sendPacket(*pkt);
 | 
					 | 
				
			||||||
	RESET_DATA;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	response = readNextPacket();
 | 
					 | 
				
			||||||
	if (!response) {
 | 
					 | 
				
			||||||
		errorMessage = "could not get a valid response!";
 | 
					 | 
				
			||||||
		return false;
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	if (response->type() != protocol::PacketTypeInfo::Init1) {
 | 
					 | 
				
			||||||
		errorMessage = "invalid response type. Got: " + response->type().name();
 | 
					 | 
				
			||||||
		return false;
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	if (response->data()[0] != 1) {
 | 
					 | 
				
			||||||
		errorMessage = "iInvalid requested login type (" + to_string((int) response->data()[0]) + " == 1)";
 | 
					 | 
				
			||||||
		return false;
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    //the second request of the manager
 | 
					 | 
				
			||||||
    memcpy(buffer, InitVersion, InitVersionLength);
 | 
					 | 
				
			||||||
    bufferIndex += InitVersionLength;
 | 
					 | 
				
			||||||
    buffer[bufferIndex++] = 0x02; //Login state
 | 
					 | 
				
			||||||
    if(response)
 | 
					 | 
				
			||||||
        memcpy(&buffer[bufferIndex], response->data().string().substr(1, 16).data(), 16);
 | 
					 | 
				
			||||||
    bufferIndex += 16; //Servers 16 bytes
 | 
					 | 
				
			||||||
	if(response)
 | 
					 | 
				
			||||||
        memcpy(&buffer[bufferIndex], response->data().string().substr(17, 4).data(), 4);
 | 
					 | 
				
			||||||
    bufferIndex += 4; //My own 16 bytes, reversed
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    pkt = new ts::protocol::ClientPacket(ts::protocol::PacketTypeInfo::Init1, pipes::buffer_view((void *) buffer, bufferIndex));
 | 
					 | 
				
			||||||
    pkt->clientId(0);
 | 
					 | 
				
			||||||
    pkt->toggle(ts::protocol::PacketFlag::Unencrypted, true);
 | 
					 | 
				
			||||||
    pkt->applyPacketId(101, 0);
 | 
					 | 
				
			||||||
	this->sendPacket(*pkt);
 | 
					 | 
				
			||||||
    RESET_DATA;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    //We got the RSA challenge
 | 
					 | 
				
			||||||
    response = readNextPacket();
 | 
					 | 
				
			||||||
    if (!response) {
 | 
					 | 
				
			||||||
        errorMessage = "could not get a valid response!";
 | 
					 | 
				
			||||||
        return false;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    if (response->type() != protocol::PacketTypeInfo::Init1) {
 | 
					 | 
				
			||||||
        errorMessage = "invalid response type";
 | 
					 | 
				
			||||||
        return false;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    if (response->data()[0] != 3) {
 | 
					 | 
				
			||||||
	    if(response->data()[0] == 127) {
 | 
					 | 
				
			||||||
		    cout << "COOCIE RESET!" << endl;
 | 
					 | 
				
			||||||
		    goto beginCoocie;
 | 
					 | 
				
			||||||
	    }
 | 
					 | 
				
			||||||
        hexdump(cout, response->data().string());
 | 
					 | 
				
			||||||
        errorMessage = "Invalid requested login type (" + to_string((int) response->data()[0]) + " == 3 | unencripted -> " + (response->hasFlag(PacketFlag::Unencrypted) ? "true" : "false") + ")";
 | 
					 | 
				
			||||||
        return false;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    //Generate puzzel response
 | 
					 | 
				
			||||||
	std::string alpha;
 | 
					 | 
				
			||||||
    pkt = solvePuzzle(response, this->clientIdentity, alpha);
 | 
					 | 
				
			||||||
	pkt->applyPacketId(101, 0);
 | 
					 | 
				
			||||||
	this->sendPacket(*pkt);
 | 
					 | 
				
			||||||
	RESET_DATA;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    cout << "manager init done" << endl;
 | 
					 | 
				
			||||||
    this->encriptAck = true;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    response = readNextPacket();
 | 
					 | 
				
			||||||
    if (!response) {
 | 
					 | 
				
			||||||
        errorMessage = "could not get a valid response!";
 | 
					 | 
				
			||||||
        return false;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    if (response->type() != protocol::PacketTypeInfo::Command) {
 | 
					 | 
				
			||||||
        errorMessage = "invalid response type: " + response->type().name();
 | 
					 | 
				
			||||||
        return false;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    auto command = response->asCommand();
 | 
					 | 
				
			||||||
    if (command.getCommand().compare("initivexpand") != 0) {
 | 
					 | 
				
			||||||
       // errorMessage = "invalid response command. Got: " + command.getCommand() + " Expected: initivexpand";
 | 
					 | 
				
			||||||
        return this->handshakeNew(command, alpha, errorMessage);
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    //std::string alpha = base64::decode(command[0]["alpha"]);
 | 
					 | 
				
			||||||
    std::string beta = base64::decode(command[0]["beta"]);
 | 
					 | 
				
			||||||
    std::string omega = base64::decode(command[0]["omega"]); //Remotes public key
 | 
					 | 
				
			||||||
    cout << "RESPONSE! -> " << command.build() << endl;
 | 
					 | 
				
			||||||
    //Read public key
 | 
					 | 
				
			||||||
    ecc_key remotePublicKey{};
 | 
					 | 
				
			||||||
    if ((err = ecc_import((const unsigned char *) omega.data(), omega.length(), &remotePublicKey)) != CRYPT_OK) {
 | 
					 | 
				
			||||||
        errorMessage = "ecc_import(...) returned " + to_string(err) + "/" + error_to_string(err);
 | 
					 | 
				
			||||||
        return false;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    if(strcmp(remotePublicKey.dp->name, "ECC-256") != 0){
 | 
					 | 
				
			||||||
        errorMessage = "invalid imported public key! Curve found " + string(remotePublicKey.dp->name);
 | 
					 | 
				
			||||||
        return false;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    size_t sharedSecretLength = 32;
 | 
					 | 
				
			||||||
    char sharedSecret[sharedSecretLength];
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    if ((err = ecc_shared_secret(clientIdentity->getKeyPair(), &remotePublicKey, (unsigned char *) sharedSecret, &sharedSecretLength)) != CRYPT_OK) {
 | 
					 | 
				
			||||||
        errorMessage = "ecc_shared_secret(...) returned " + to_string(err) + "/" + error_to_string(err);
 | 
					 | 
				
			||||||
        return false;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    if (!setupSharedSecret(alpha, beta, string(sharedSecret, sharedSecretLength), error)) {
 | 
					 | 
				
			||||||
        errorMessage = "setupSharedSecret(...) failed: " + error;
 | 
					 | 
				
			||||||
        return false;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    //this->readQueue[PacketType::Command.type()]->reset();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    //TS 3.1
 | 
					 | 
				
			||||||
    /*
 | 
					 | 
				
			||||||
    response = readNextPacket();
 | 
					 | 
				
			||||||
    if (!response) {
 | 
					 | 
				
			||||||
        errorMessage = "could not get a valid response!";
 | 
					 | 
				
			||||||
        return false;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    if (response->type() != protocol::PacketType::Command) {
 | 
					 | 
				
			||||||
        errorMessage = "invalid response type: " + response->type().name();
 | 
					 | 
				
			||||||
        return false;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    command = response->asCommand();
 | 
					 | 
				
			||||||
    cout << "Having initiv2 -> " << response->data() << endl;
 | 
					 | 
				
			||||||
     */
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    this->idManager.nextPacketId(PacketTypeInfo::Command);
 | 
					 | 
				
			||||||
    Command clientinit("clientinit");
 | 
					 | 
				
			||||||
    //94ec66de-5940-4e38-b002-970df0cf6c94,62444179-0d99-42ba-a45c-c6b1557d079a,d95f9901-c42d-4bac-8849-7164fd9e2310
 | 
					 | 
				
			||||||
    //clientinit["client_badges"] = "badges=450f81c1-ab41-4211-a338-222fa94ed157,c9e97536-5a2d-4c8e-a135-af404587a472,94ec66de-5940-4e38-b002-970df0cf6c94"; //,62444179-0d99-42ba-a45c-c6b1557d079a
 | 
					 | 
				
			||||||
    clientinit["client_nickname"] = "Wolf C++ XXXX";
 | 
					 | 
				
			||||||
    clientinit["client_version"] = "3.1 [Build: 1471417187]";
 | 
					 | 
				
			||||||
    clientinit["client_platform"] = "Windows";
 | 
					 | 
				
			||||||
    clientinit["client_version_sign"] = "Vr9F7kbVorcrkV5b/Iw+feH9qmDGvfsW8tpa737zhc1fDpK5uaEo6M5l2DzgaGqqOr3GKl5A7PF9Sj6eTM26Aw==";
 | 
					 | 
				
			||||||
    clientinit["client_input_hardware"] = true;
 | 
					 | 
				
			||||||
    clientinit["client_output_hardware"] = true;
 | 
					 | 
				
			||||||
    clientinit["client_default_channel"] = "";
 | 
					 | 
				
			||||||
    clientinit["client_default_channel_password"] = "";
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    string password;
 | 
					 | 
				
			||||||
    if(!password.empty()){
 | 
					 | 
				
			||||||
        char passwordBuffer[SHA_DIGEST_LENGTH];
 | 
					 | 
				
			||||||
        SHA1((const unsigned char *) password.data(), password.length(), (unsigned char *) passwordBuffer);
 | 
					 | 
				
			||||||
        password = base64_encode(string(passwordBuffer, SHA_DIGEST_LENGTH));
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    clientinit["client_server_password"] = password;
 | 
					 | 
				
			||||||
    clientinit["client_meta_data"] = "";
 | 
					 | 
				
			||||||
    clientinit["client_key_offset"] = this->clientIdentity->lastValidKeyOffset();
 | 
					 | 
				
			||||||
    clientinit["client_nickname_phonetic"] = "";
 | 
					 | 
				
			||||||
    clientinit["client_default_token"] = "";
 | 
					 | 
				
			||||||
    clientinit["hwid"] = "123,456123123123";
 | 
					 | 
				
			||||||
    sendCommand(clientinit);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    while(true){
 | 
					 | 
				
			||||||
        response = readNextPacket();
 | 
					 | 
				
			||||||
        if (!response) {
 | 
					 | 
				
			||||||
            errorMessage = "could not get a valid response!";
 | 
					 | 
				
			||||||
            return false;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        if(response->type() == PacketTypeInfo::Ack) continue;
 | 
					 | 
				
			||||||
        break;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    //TODO check ack id
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    if (!response) {
 | 
					 | 
				
			||||||
        errorMessage = "could not get a valid response!";
 | 
					 | 
				
			||||||
        return false;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    if (response->type() != protocol::PacketTypeInfo::Command) {
 | 
					 | 
				
			||||||
        errorMessage = "invalid response type: " + response->type().name();
 | 
					 | 
				
			||||||
        return false;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    if(response->asCommand().getCommand() == "initserver"){ //Got success
 | 
					 | 
				
			||||||
        this->handleQueueLock.lock();
 | 
					 | 
				
			||||||
        this->handleQueue.push_front(response);
 | 
					 | 
				
			||||||
        this->handleQueueLock.unlock();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        this->setClientId(response->asCommand()["aclid"]);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        this->autoHandle = true;
 | 
					 | 
				
			||||||
        cout << "Successfull connected!" << endl;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        /*
 | 
					 | 
				
			||||||
        std::thread([&](){
 | 
					 | 
				
			||||||
            usleep(1000 * 1000);
 | 
					 | 
				
			||||||
            cout << " -> send extra command" << endl;
 | 
					 | 
				
			||||||
            //this->sendCommand(Command("channelsubscribeall return_code=1:i"));
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            while(true){
 | 
					 | 
				
			||||||
                //this->sendCommand(Command("getconnectioninfo clid=320 return_code=1:112"));
 | 
					 | 
				
			||||||
                //this->sendCommand(Command("ftgetfilelist cid=0 cpw path=\\/icons return_code=1:z0"));
 | 
					 | 
				
			||||||
                this->sendCommand(Command("servergrouppermlist sgid=6 return_code=1:112"));
 | 
					 | 
				
			||||||
                usleep(10 * 1000 * 1000);
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
            //Command cmd("channelgetdescription cid=1 return_code=1:3o");
 | 
					 | 
				
			||||||
            //Command cmd("clientupdate client_nickname=WolverinDEV22 return_code=__1_");
 | 
					 | 
				
			||||||
            //Command cmd("clientdisconnect reasonid=8 reasonmsg=leaving");
 | 
					 | 
				
			||||||
            //this->sendCommand(Command("permissionlist return_code=__1_"));
 | 
					 | 
				
			||||||
            //this->sendCommand(Command("clientgetvariables clid=" + to_string(this->clientId)));
 | 
					 | 
				
			||||||
        }).detach();
 | 
					 | 
				
			||||||
         */
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        return true;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    cout << "Invalid connect: " << response->data() << endl;
 | 
					 | 
				
			||||||
    //TODO error handling
 | 
					 | 
				
			||||||
    return true;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
inline ClientPacket* solvePuzzle(shared_ptr<ServerPacket> response, Identity *identity, std::string &alpha) {
 | 
					 | 
				
			||||||
    uint32_t puzzelLength = be2le32(&((char*) response->data().data_ptr())[1 + 128]); //1 for the first byte (the state byte)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    auto buffer = (char*) response->data().data_ptr();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    char alphaBuffer[10];
 | 
					 | 
				
			||||||
    for (int index = 0; index < 10; index++)
 | 
					 | 
				
			||||||
        alphaBuffer[index] = 0; //rand();
 | 
					 | 
				
			||||||
	alpha = string(alphaBuffer, 10);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    //Generating command
 | 
					 | 
				
			||||||
    auto pkey = identity->publicKey();
 | 
					 | 
				
			||||||
    ts::Command command("clientinitiv", {
 | 
					 | 
				
			||||||
            {"alpha", base64_encode(alphaBuffer, 10)},
 | 
					 | 
				
			||||||
            {"omega", pkey},
 | 
					 | 
				
			||||||
            {"ip", ""},
 | 
					 | 
				
			||||||
            {"ot", 1}                       //Required by 3.1
 | 
					 | 
				
			||||||
    });
 | 
					 | 
				
			||||||
    std::string cmd = command.build();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    //Sloving puzzel
 | 
					 | 
				
			||||||
    mp_int x{};
 | 
					 | 
				
			||||||
    mp_int n{};
 | 
					 | 
				
			||||||
    mp_int result{};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    //mp_init_multi(&x, &n, &result);
 | 
					 | 
				
			||||||
    mp_init(&x);
 | 
					 | 
				
			||||||
    mp_init(&n);
 | 
					 | 
				
			||||||
    mp_init(&result);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    char numBuffer[2048];
 | 
					 | 
				
			||||||
    mp_read_unsigned_bin(&x, (const unsigned char *) &response->data()[1], 64); //One offset
 | 
					 | 
				
			||||||
    mp_read_unsigned_bin(&n, (const unsigned char *) &response->data()[1 + 64], 64); //1 + 64 offset
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    cout << "X: " << toString(&x) << endl;
 | 
					 | 
				
			||||||
    cout << "N: " << toString(&n) << endl;
 | 
					 | 
				
			||||||
    cout << "Length: " << puzzelLength << endl;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    mp_int exp{};
 | 
					 | 
				
			||||||
    mp_init(&exp);
 | 
					 | 
				
			||||||
    mp_2expt(&exp, puzzelLength);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    //x ** (2 ** puzzelLength) mod n
 | 
					 | 
				
			||||||
    int err = 0;
 | 
					 | 
				
			||||||
    if ((err = mp_exptmod(&x, &exp, &n, &result)) != CRYPT_OK) {
 | 
					 | 
				
			||||||
        cerr << "Invalid crypt: " << err << "/" << error_to_string(err) << endl;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    int resultBufferLength = mp_unsigned_bin_size(&result);
 | 
					 | 
				
			||||||
    char resultBuffer[resultBufferLength];
 | 
					 | 
				
			||||||
    mp_to_unsigned_bin(&result, (unsigned char *) resultBuffer);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    //mp_clear_multi(&x, &n, &exp, &result);
 | 
					 | 
				
			||||||
    mp_clear(&x);
 | 
					 | 
				
			||||||
    mp_clear(&n);
 | 
					 | 
				
			||||||
    mp_clear(&exp);
 | 
					 | 
				
			||||||
    mp_clear(&result);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    size_t packetBufferLength = InitVersionLength + 1 + 232 + 64 + cmd.length();
 | 
					 | 
				
			||||||
    char packetBuffer[packetBufferLength];
 | 
					 | 
				
			||||||
    memset(packetBuffer, 0, packetBufferLength);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    memcpy(packetBuffer, InitVersion, InitVersionLength);
 | 
					 | 
				
			||||||
    packetBuffer[InitVersionLength] = 0x04;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    //Copy old data
 | 
					 | 
				
			||||||
    memcpy(&packetBuffer[InitVersionLength + 1], &response->data()[1], 232);
 | 
					 | 
				
			||||||
    memcpy(&packetBuffer[InitVersionLength + 1 + 232 + (64 - resultBufferLength)], resultBuffer, resultBufferLength);
 | 
					 | 
				
			||||||
    memcpy(&packetBuffer[InitVersionLength + 1 + 232 + 64], cmd.data(), cmd.length());
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    cout << "sending puzzel sulution" << endl;
 | 
					 | 
				
			||||||
    auto pkt = new ts::protocol::ClientPacket(ts::protocol::PacketTypeInfo::Init1, pipes::buffer_view((void *) packetBuffer, packetBufferLength));
 | 
					 | 
				
			||||||
    pkt->clientId(0);
 | 
					 | 
				
			||||||
    pkt->toggle(ts::protocol::PacketFlag::Unencrypted, true);
 | 
					 | 
				
			||||||
    return pkt;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
@ -1,158 +0,0 @@
 | 
				
			|||||||
#include <protocol/Packet.h>
 | 
					 | 
				
			||||||
#include <arpa/inet.h>
 | 
					 | 
				
			||||||
#include "Connection.h"
 | 
					 | 
				
			||||||
#include "misc/base64.h"
 | 
					 | 
				
			||||||
#include "misc/endianness.h"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
using namespace std;
 | 
					 | 
				
			||||||
using namespace ts;
 | 
					 | 
				
			||||||
using namespace ts::connection;
 | 
					 | 
				
			||||||
using namespace ts::protocol;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
//notifystatusfiletransfer clientftfid=4093 status=2063 msg=lost\sfile\stransfer\sconnection size=16384
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
extern void hexdump(std::ostream& outs, const std::string& s, size_t line_len = 16);
 | 
					 | 
				
			||||||
inline void downloadStuff(std::string key, uint16_t port, uint64_t size){
 | 
					 | 
				
			||||||
    threads::Thread([key, port, size](){
 | 
					 | 
				
			||||||
        int socketId = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
 | 
					 | 
				
			||||||
        assert(socketId > 1);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        sockaddr_in server;
 | 
					 | 
				
			||||||
        server.sin_addr.s_addr = inet_addr("127.0.0.1");
 | 
					 | 
				
			||||||
        server.sin_family = AF_INET;
 | 
					 | 
				
			||||||
        server.sin_port = htons( port );
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        //Connect to remote server
 | 
					 | 
				
			||||||
        if (connect(socketId , (struct sockaddr *)&server , sizeof(server)) < 0)
 | 
					 | 
				
			||||||
        {
 | 
					 | 
				
			||||||
            perror("connect failed. Error");
 | 
					 | 
				
			||||||
            return;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        uint32_t readed = 0;
 | 
					 | 
				
			||||||
        assert(send(socketId, key.data(), key.length(), 0) > 0);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        while(readed < size + 3){
 | 
					 | 
				
			||||||
            char buffer[size];
 | 
					 | 
				
			||||||
            auto readedBytes = recv(socketId, buffer, size - readed, MSG_DONTWAIT);
 | 
					 | 
				
			||||||
            if(readedBytes < 0) {
 | 
					 | 
				
			||||||
                //cerr << "Invalid ft read" << endl;
 | 
					 | 
				
			||||||
                continue;
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
            if(readedBytes == 0){
 | 
					 | 
				
			||||||
                continue;
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
            hexdump(cout, string(buffer, readedBytes));
 | 
					 | 
				
			||||||
            readed += readedBytes;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        cout << "File downloaded!" << endl;
 | 
					 | 
				
			||||||
    }).detach();
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void ServerConnection::handlePacketAck(std::shared_ptr<protocol::ServerPacket> packet) {
 | 
					 | 
				
			||||||
    auto packetId = be2le16((const char*) packet->data().data_ptr());
 | 
					 | 
				
			||||||
#if defined(DEBUG_PACKET_LOG) || defined(LOG_ACK)
 | 
					 | 
				
			||||||
    cout << "Got ack for " << packetId << endl;
 | 
					 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void ServerConnection::handlePacketCommand(std::shared_ptr<protocol::ServerPacket> packet) {
 | 
					 | 
				
			||||||
	auto command = packet->asCommand();
 | 
					 | 
				
			||||||
#if defined(DEBUG_PACKET_LOG) || defined(LOG_CMD)
 | 
					 | 
				
			||||||
	cout << "[Server -> Client][" << packet->type().name() << "] " << packet->data() << endl;
 | 
					 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
	if (command.getCommand().compare("notifyconnectioninforequest") == 0) { //TODO
 | 
					 | 
				
			||||||
		cout << "Send response" << endl;
 | 
					 | 
				
			||||||
		Command cmd(
 | 
					 | 
				
			||||||
				string("setconnectioninfo"), {
 | 
					 | 
				
			||||||
						{"connection_ping",                                     10000000},
 | 
					 | 
				
			||||||
						{"connection_ping_deviation",                           10000000},
 | 
					 | 
				
			||||||
						{"connection_packets_sent_speech",                      0},
 | 
					 | 
				
			||||||
						{"connection_packets_sent_keepalive",                   0},
 | 
					 | 
				
			||||||
						{"connection_packets_sent_control",                     rand()},
 | 
					 | 
				
			||||||
						{"connection_bytes_sent_speech",                        0},
 | 
					 | 
				
			||||||
						{"connection_bytes_sent_keepalive",                     0},
 | 
					 | 
				
			||||||
						{"connection_bytes_sent_control",                       0},
 | 
					 | 
				
			||||||
						{"connection_packets_received_speech",                  0},
 | 
					 | 
				
			||||||
						{"connection_packets_received_keepalive",               0},
 | 
					 | 
				
			||||||
						{"connection_packets_received_control",                 0},
 | 
					 | 
				
			||||||
						{"connection_bytes_received_speech",                    0},
 | 
					 | 
				
			||||||
						{"connection_bytes_received_keepalive",                 0},
 | 
					 | 
				
			||||||
						{"connection_bytes_received_control",                   0},
 | 
					 | 
				
			||||||
						{"connection_server2client_packetloss_speech",          10000000},
 | 
					 | 
				
			||||||
						{"connection_server2client_packetloss_keepalive",       10000000},
 | 
					 | 
				
			||||||
						{"connection_server2client_packetloss_control",         10000000},
 | 
					 | 
				
			||||||
						{"connection_server2client_packetloss_total",           10000000},
 | 
					 | 
				
			||||||
						{"connection_bandwidth_sent_last_second_speech",        0},
 | 
					 | 
				
			||||||
						{"connection_bandwidth_sent_last_second_keepalive",     0},
 | 
					 | 
				
			||||||
						{"connection_bandwidth_sent_last_second_control",       0},
 | 
					 | 
				
			||||||
						{"connection_bandwidth_sent_last_minute_speech",        0},
 | 
					 | 
				
			||||||
						{"connection_bandwidth_sent_last_minute_keepalive",     0},
 | 
					 | 
				
			||||||
						{"connection_bandwidth_sent_last_minute_control",       0},
 | 
					 | 
				
			||||||
						{"connection_bandwidth_received_last_second_speech",    0},
 | 
					 | 
				
			||||||
						{"connection_bandwidth_received_last_second_keepalive", 0},
 | 
					 | 
				
			||||||
						{"connection_bandwidth_received_last_second_control",   0},
 | 
					 | 
				
			||||||
						{"connection_bandwidth_received_last_minute_speech",    0},
 | 
					 | 
				
			||||||
						{"connection_bandwidth_received_last_minute_keepalive", 0},
 | 
					 | 
				
			||||||
						{"connection_bandwidth_received_last_minute_control",   0}
 | 
					 | 
				
			||||||
				}
 | 
					 | 
				
			||||||
		);
 | 
					 | 
				
			||||||
		sendCommand(cmd, true);
 | 
					 | 
				
			||||||
	} else if (command.command() == "notifyserverupdated") {
 | 
					 | 
				
			||||||
#if defined(DEBUG_PACKET_LOG) || defined(LOG_CMD)
 | 
					 | 
				
			||||||
		cout << "notifyserverupdated -> " << endl;
 | 
					 | 
				
			||||||
		cout << "Last data: " << packet->data().string().substr(packet->data().length() - 10) << endl;
 | 
					 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
	} else if (command.command() == "notifystartdownload") {
 | 
					 | 
				
			||||||
		cout << "Client download: " << command.build() << endl;
 | 
					 | 
				
			||||||
		auto port = command["port"].as<uint16_t>();
 | 
					 | 
				
			||||||
		auto key = command["ftkey"].string();
 | 
					 | 
				
			||||||
		auto size = command["size"].as<uint64_t>();
 | 
					 | 
				
			||||||
		downloadStuff(key, port, size);
 | 
					 | 
				
			||||||
	} else if (command.command() == "channellist") {
 | 
					 | 
				
			||||||
		cout << "Breaking ack" << endl;
 | 
					 | 
				
			||||||
		for (int index = 0; index < command.bulkCount(); index++) {
 | 
					 | 
				
			||||||
			this->channels.push_back(command[index]["cid"].as<ChannelId>());
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
void ServerConnection::handlePacketVoice(std::shared_ptr<protocol::ServerPacket> packet) {}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static int pingIndex = 0;
 | 
					 | 
				
			||||||
void ServerConnection::handlePacketPing(std::shared_ptr<protocol::ServerPacket> packet) {
 | 
					 | 
				
			||||||
    if(packet->type() == PacketTypeInfo::Pong){
 | 
					 | 
				
			||||||
        //cout << "[PING] gota " << be2le16(packet->data().data()) << endl;
 | 
					 | 
				
			||||||
        return;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    char buffer[2];
 | 
					 | 
				
			||||||
    le2be16(packet->packetId(), buffer);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    ClientPacket pkt(PacketTypeInfo::Pong, pipes::buffer_view{buffer, 2});
 | 
					 | 
				
			||||||
    pkt.enableFlag(PacketFlag::Unencrypted);
 | 
					 | 
				
			||||||
    sendPacket(pkt);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    ClientPacket ping(PacketTypeInfo::Ping, pipes::buffer_view{buffer, 0});
 | 
					 | 
				
			||||||
    ping.enableFlag(PacketFlag::Unencrypted);
 | 
					 | 
				
			||||||
    sendPacket(ping);
 | 
					 | 
				
			||||||
    //cout << "[PING] Reqe " << ping.packetId() << endl;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    //cout << "[PONG] Send " << packet->packetId()  << endl;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    if(this->clientId > 0 && this->channels.size() > 0) {
 | 
					 | 
				
			||||||
        Command command("clientmove");
 | 
					 | 
				
			||||||
        command["clid"] = this->clientId;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        auto idx = rand() % this->channels.size();
 | 
					 | 
				
			||||||
        command["cid"] = this->channels[idx];
 | 
					 | 
				
			||||||
        this->sendCommand(command);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        std::thread([&] {
 | 
					 | 
				
			||||||
        	threads::self::sleep_for(chrono::seconds(1));
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	        Command cmd("channelcreate");
 | 
					 | 
				
			||||||
	        cmd["channel_name"] = to_string(rand()) + "_" + to_string(rand());
 | 
					 | 
				
			||||||
	        //this->sendCommand(cmd);
 | 
					 | 
				
			||||||
        }).detach();
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
@ -1,154 +0,0 @@
 | 
				
			|||||||
#include <ed25519/ed25519.h>
 | 
					 | 
				
			||||||
#include <ed25519/sha512.h>
 | 
					 | 
				
			||||||
#include <misc/base64.h>
 | 
					 | 
				
			||||||
#include <misc/digest.h>
 | 
					 | 
				
			||||||
#include "Connection.h"
 | 
					 | 
				
			||||||
#include "License.h"
 | 
					 | 
				
			||||||
#include <log/LogUtils.h>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
using namespace std;
 | 
					 | 
				
			||||||
using namespace std::chrono;
 | 
					 | 
				
			||||||
using namespace ts;
 | 
					 | 
				
			||||||
using namespace license::teamspeak;
 | 
					 | 
				
			||||||
using namespace ts::connection;
 | 
					 | 
				
			||||||
using namespace ts::protocol;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
int __ed_sha512_init(sha512_context* ctx) {
 | 
					 | 
				
			||||||
	//assert(!ctx->context);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	ctx->context = new hash_state{};
 | 
					 | 
				
			||||||
	return sha512_init((hash_state*) ctx->context) == CRYPT_OK;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
int __ed_sha512_final(sha512_context* ctx, unsigned char *out) {
 | 
					 | 
				
			||||||
	assert(ctx->context);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	auto result = sha512_done((hash_state*) ctx->context, out) == CRYPT_OK;
 | 
					 | 
				
			||||||
	delete (hash_state*) ctx->context;
 | 
					 | 
				
			||||||
	return result;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
int __ed_sha512_update(sha512_context* ctx, const unsigned char *msg, size_t len) {
 | 
					 | 
				
			||||||
	assert(ctx->context);
 | 
					 | 
				
			||||||
	return sha512_process((hash_state*) ctx->context, msg, len) == CRYPT_OK;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static sha512_functions __ed_sha512_functions {
 | 
					 | 
				
			||||||
		__ed_sha512_init,
 | 
					 | 
				
			||||||
		__ed_sha512_final,
 | 
					 | 
				
			||||||
		__ed_sha512_update
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
bool ServerConnection::handshakeNew(Command &initivexpand2, const std::string& alpha, std::string &errorMessage) {
 | 
					 | 
				
			||||||
	if(&__ed_sha512_functions != &_ed_sha512_functions)
 | 
					 | 
				
			||||||
		_ed_sha512_functions = __ed_sha512_functions;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	cout << initivexpand2.build() << endl;
 | 
					 | 
				
			||||||
	u_char seed[32 * 2];
 | 
					 | 
				
			||||||
	u_char clientPrivateKey[32];
 | 
					 | 
				
			||||||
	u_char clientPublicKey[32];
 | 
					 | 
				
			||||||
	ed25519_create_keypair(clientPublicKey, clientPrivateKey, seed);
 | 
					 | 
				
			||||||
	cout << "Client key: " << base64::encode((char*) clientPrivateKey, 32) << endl;
 | 
					 | 
				
			||||||
	cout << "Privet key:" << endl;
 | 
					 | 
				
			||||||
	hexDump(clientPrivateKey, 32);
 | 
					 | 
				
			||||||
	cout << "Public key:" << endl;
 | 
					 | 
				
			||||||
	hexDump(clientPublicKey, 32);
 | 
					 | 
				
			||||||
	auto license = base64::decode(initivexpand2["l"]);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	auto licensestream = stringstream(license);
 | 
					 | 
				
			||||||
	auto chain = LicenseChain::parse(licensestream, errorMessage);
 | 
					 | 
				
			||||||
	if(!chain) return false;
 | 
					 | 
				
			||||||
	chain->print();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	unique_ptr<ecc_key> serverPublic(new ecc_key{});
 | 
					 | 
				
			||||||
	auto omega = base64::decode(initivexpand2["omega"]);
 | 
					 | 
				
			||||||
	ecc_import((u_char*) omega.data(), omega.length(), serverPublic.get());
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	//7B 1E AC 02 CE 77 35 0E EF C4 5C 1C F7 54 04 87 A9 A7 64 A7 8F 04 F7 53 58 64 84 D7 0A 97 F2 63
 | 
					 | 
				
			||||||
	//[0x7b, 0x1e, 0xac, 0x2, 0xce, 0x77, 0x35, 0xe, 0xef, 0xc4, 0x5c, 0x1c, 0xf7, 0x54, 0x4, 0x87, 0xa9, 0xa7, 0x64, 0xa7, 0x8f, 0x4, 0xf7, 0x53, 0x58, 0x64, 0x84, 0xd7, 0xa, 0x97, 0xf2, 0xe3]
 | 
					 | 
				
			||||||
	//License signed from server :)
 | 
					 | 
				
			||||||
	auto licenseHash = digest::sha256(license);
 | 
					 | 
				
			||||||
	auto licenseSign = base64::decode(initivexpand2["proof"]);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	int state;
 | 
					 | 
				
			||||||
	assert(ecc_verify_hash((u_char*) licenseSign.c_str(), licenseSign.length(), (u_char*) licenseHash.c_str(), licenseHash.length(), &state, serverPublic.get()) == CRYPT_OK);
 | 
					 | 
				
			||||||
	cout << "State: " << state << endl;
 | 
					 | 
				
			||||||
	assert(state == 1);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	//EK!
 | 
					 | 
				
			||||||
	this->idManager.nextPacketId(PacketTypeInfo::Command);
 | 
					 | 
				
			||||||
	cout << this->idManager.currentPacketId(PacketTypeInfo::Command) << endl;
 | 
					 | 
				
			||||||
	Command clientek("clientek");
 | 
					 | 
				
			||||||
	clientek["ek"] = base64::encode((char*) clientPublicKey, 32);
 | 
					 | 
				
			||||||
	auto rawProof = string((char*) clientPublicKey, 32) + base64::decode(initivexpand2["beta"]);
 | 
					 | 
				
			||||||
	cout << " -> " << rawProof.length() << endl;
 | 
					 | 
				
			||||||
	size_t signBufferLength = 120;
 | 
					 | 
				
			||||||
	char signBuffer[signBufferLength];
 | 
					 | 
				
			||||||
	prng_state prngState{};
 | 
					 | 
				
			||||||
	memset(&prngState, 0, sizeof(prngState));
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	cout << "Data: " << base64::encode(rawProof) << endl;
 | 
					 | 
				
			||||||
	cout << "KEY: " << this->clientIdentity->privateKey() << endl;
 | 
					 | 
				
			||||||
	rawProof = digest::sha256(rawProof);
 | 
					 | 
				
			||||||
	assert(ecc_sign_hash((u_char*) rawProof.data(), rawProof.length(), (u_char*) signBuffer, &signBufferLength, &prngState, find_prng("sprng"), this->clientIdentity->getKeyPair()) == CRYPT_OK);
 | 
					 | 
				
			||||||
	cout << "ecc_sign_hash() -> " << base64::encode(signBuffer, signBufferLength) << endl;
 | 
					 | 
				
			||||||
	clientek["proof"] = base64::encode(signBuffer, signBufferLength);
 | 
					 | 
				
			||||||
	this->sendCommand(clientek, false);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	//TODO magic stuff
 | 
					 | 
				
			||||||
	shared_ptr<ServerPacket> response;
 | 
					 | 
				
			||||||
	response = readNextPacket();
 | 
					 | 
				
			||||||
	if (!response) {
 | 
					 | 
				
			||||||
		errorMessage = "could not get a valid response!";
 | 
					 | 
				
			||||||
		return false;
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	cout << "Type: " << response->type().name() << endl;
 | 
					 | 
				
			||||||
	cout << "ID: " << (int) response->data()[0] << " " << (int) response->data()[1] << endl;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	LicensePublicKey serverroot;
 | 
					 | 
				
			||||||
	memcpy(serverroot, public_root, 32);
 | 
					 | 
				
			||||||
	if(initivexpand2[0].has("root")) {
 | 
					 | 
				
			||||||
		cout << "Cot costume server root!" << endl;
 | 
					 | 
				
			||||||
		auto root = base64::decode(initivexpand2["root"]);
 | 
					 | 
				
			||||||
		memcpy(serverroot, root.data(), 32);
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	cout << "Public root key: " << endl;
 | 
					 | 
				
			||||||
	for(const auto& e : serverroot)
 | 
					 | 
				
			||||||
		cout << hex << "0x" << (int) (uint8_t) e << " " << endl;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	string sharedData;
 | 
					 | 
				
			||||||
	this->cryptionHandler->setupSharedSecretNew(alpha, base64::decode(initivexpand2["beta"]), (char*) clientPrivateKey, (char*) chain->generatePublicKey(serverroot).data());
 | 
					 | 
				
			||||||
	//this->cryptionHandler->setupSharedSecretNew(alpha, base64::decode(initivexpand2["beta"]), (char*) clientPrivateKey, (char*) public_tea_root);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	threads::self::sleep_for(milliseconds(250));
 | 
					 | 
				
			||||||
	Command clientinit("clientinit");
 | 
					 | 
				
			||||||
	//94ec66de-5940-4e38-b002-970df0cf6c94,62444179-0d99-42ba-a45c-c6b1557d079a,d95f9901-c42d-4bac-8849-7164fd9e2310
 | 
					 | 
				
			||||||
	//clientinit["client_badges"] = "badges=450f81c1-ab41-4211-a338-222fa94ed157,c9e97536-5a2d-4c8e-a135-af404587a472,94ec66de-5940-4e38-b002-970df0cf6c94"; //,62444179-0d99-42ba-a45c-c6b1557d079a
 | 
					 | 
				
			||||||
	clientinit["client_nickname"] = "Wolf C++ XX";
 | 
					 | 
				
			||||||
	clientinit["client_version"] = "3.1.8 [Build: 1516614607]";
 | 
					 | 
				
			||||||
	clientinit["client_platform"] = "Windows";
 | 
					 | 
				
			||||||
	clientinit["client_version_sign"] = "gDEgQf/BiOQZdAheKccM1XWcMUj2OUQqt75oFuvF2c0MQMXyv88cZQdUuckKbcBRp7RpmLInto4PIgd7mPO7BQ==";
 | 
					 | 
				
			||||||
	clientinit["client_input_hardware"] = true;
 | 
					 | 
				
			||||||
	clientinit["client_output_hardware"] = true;
 | 
					 | 
				
			||||||
	clientinit["client_default_channel"] = "";
 | 
					 | 
				
			||||||
	clientinit["client_default_channel_password"] = "";
 | 
					 | 
				
			||||||
	clientinit["client_server_password"] = "";
 | 
					 | 
				
			||||||
	clientinit["client_meta_data"] = "";
 | 
					 | 
				
			||||||
	clientinit["client_key_offset"] = this->clientIdentity->lastValidKeyOffset();
 | 
					 | 
				
			||||||
	clientinit["client_nickname_phonetic"] = "";
 | 
					 | 
				
			||||||
	clientinit["client_default_token"] = "";
 | 
					 | 
				
			||||||
	clientinit["hwid"] = "123,456123123123";
 | 
					 | 
				
			||||||
	sendCommand(clientinit);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	this->autoHandle = true;
 | 
					 | 
				
			||||||
	/*
 | 
					 | 
				
			||||||
	response = readNextPacket();
 | 
					 | 
				
			||||||
	if (!response) {
 | 
					 | 
				
			||||||
		errorMessage = "could not get a valid response!";
 | 
					 | 
				
			||||||
		return false;
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	 */
 | 
					 | 
				
			||||||
	return true;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
@ -1,115 +0,0 @@
 | 
				
			|||||||
//
 | 
					 | 
				
			||||||
// Created by root on 13.10.17.
 | 
					 | 
				
			||||||
//
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#include "FilteredUDPSocket.h"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#include <iostream>
 | 
					 | 
				
			||||||
#include <cstring>
 | 
					 | 
				
			||||||
#include <ifaddrs.h>
 | 
					 | 
				
			||||||
#include <netinet/udp.h>   //Provides declarations for udp header
 | 
					 | 
				
			||||||
#include <netinet/ip.h>    //Provides declarations for ip header
 | 
					 | 
				
			||||||
#include <arpa/inet.h>
 | 
					 | 
				
			||||||
#include <sys/socket.h>
 | 
					 | 
				
			||||||
#include <sys/types.h>
 | 
					 | 
				
			||||||
#include <arpa/inet.h>
 | 
					 | 
				
			||||||
#include <linux/if_ether.h>
 | 
					 | 
				
			||||||
#include <linux/filter.h>
 | 
					 | 
				
			||||||
#include <chrono>
 | 
					 | 
				
			||||||
#include <zconf.h>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
using namespace std;
 | 
					 | 
				
			||||||
using namespace std::chrono;
 | 
					 | 
				
			||||||
using namespace ts::connection;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
FilteredUdpSocket::FilteredUdpSocket() {}
 | 
					 | 
				
			||||||
FilteredUdpSocket::~FilteredUdpSocket() {}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
bool FilteredUdpSocket::setup(sockaddr_in * remoteAddr) {
 | 
					 | 
				
			||||||
    srand(system_clock::now().time_since_epoch().count());   // should only be called once
 | 
					 | 
				
			||||||
    int r = (lrand48() % (50 * 1000)) + 1000;      // returns a pseudo-random integer between 0 and RAND_MAX
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    this->remoteAdress = new sockaddr_in;
 | 
					 | 
				
			||||||
    memcpy(this->remoteAdress, remoteAddr, sizeof(sockaddr_in));
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    this->socketDescriptor = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
 | 
					 | 
				
			||||||
    if(this->socketDescriptor < 0){
 | 
					 | 
				
			||||||
        cerr << "Invalid socket create: " << errno << " - " << this->socketDescriptor << " -> " << strerror(errno) << endl;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    int allow = 1;
 | 
					 | 
				
			||||||
    setsockopt(this->socketDescriptor, SOL_SOCKET, SO_REUSEADDR, &allow, sizeof(int));
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    this->localAdress = new sockaddr_in;
 | 
					 | 
				
			||||||
    memset((char *) this->localAdress, 0, sizeof(sockaddr_in));
 | 
					 | 
				
			||||||
    localAdress->sin_family = AF_INET;
 | 
					 | 
				
			||||||
    localAdress->sin_addr.s_addr = htonl(INADDR_ANY);
 | 
					 | 
				
			||||||
    localAdress->sin_port = htons(r);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* sudo tcpdump -q udp port 256  -dd */
 | 
					 | 
				
			||||||
    struct sock_filter code[ ] = {
 | 
					 | 
				
			||||||
            { 0x28, 0, 0, 0x0000000c },
 | 
					 | 
				
			||||||
            { 0x15, 0, 8, 0x000086dd },
 | 
					 | 
				
			||||||
            { 0x30, 0, 0, 0x00000014 },
 | 
					 | 
				
			||||||
            { 0x15, 2, 0, 0x00000084 },
 | 
					 | 
				
			||||||
            { 0x15, 1, 0, 0x00000006 },
 | 
					 | 
				
			||||||
            { 0x15, 0, 17, 0x00000011 },
 | 
					 | 
				
			||||||
            { 0x28, 0, 0, 0x00000036 },
 | 
					 | 
				
			||||||
            { 0x15, 14, 0, 0x00002fbd },
 | 
					 | 
				
			||||||
            { 0x28, 0, 0, 0x00000038 },
 | 
					 | 
				
			||||||
            { 0x15, 12, 13, 0x00002fbd },
 | 
					 | 
				
			||||||
            { 0x15, 0, 12, 0x00000800 },
 | 
					 | 
				
			||||||
            { 0x30, 0, 0, 0x00000017 },
 | 
					 | 
				
			||||||
            { 0x15, 2, 0, 0x00000084 },
 | 
					 | 
				
			||||||
            { 0x15, 1, 0, 0x00000006 },
 | 
					 | 
				
			||||||
            { 0x15, 0, 8, 0x00000011 },
 | 
					 | 
				
			||||||
            { 0x28, 0, 0, 0x00000014 },
 | 
					 | 
				
			||||||
            { 0x45, 6, 0, 0x00001fff },
 | 
					 | 
				
			||||||
            { 0xb1, 0, 0, 0x0000000e },
 | 
					 | 
				
			||||||
            { 0x48, 0, 0, 0x0000000e },
 | 
					 | 
				
			||||||
            { 0x15, 2, 0, 0x00002fbd },
 | 
					 | 
				
			||||||
            { 0x48, 0, 0, 0x00000010 },
 | 
					 | 
				
			||||||
            { 0x15, 0, 1, 0x00002fbd },
 | 
					 | 
				
			||||||
            { 0x6, 0, 0, 0x00040000 },
 | 
					 | 
				
			||||||
            { 0x6, 0, 0, 0x00000000 },
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    };
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    struct sock_fprog bpf = {
 | 
					 | 
				
			||||||
            .len = sizeof(code) / sizeof(*code),
 | 
					 | 
				
			||||||
            .filter = code,
 | 
					 | 
				
			||||||
    };
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    //auto response = setsockopt(this->socketDescriptor, SOL_SOCKET, SO_ATTACH_FILTER, &bpf, sizeof(bpf));
 | 
					 | 
				
			||||||
    //if (response < 0) cerr << "Invalid attach!" << endl;
 | 
					 | 
				
			||||||
    /* ... bail out ... */
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    /*
 | 
					 | 
				
			||||||
     *
 | 
					 | 
				
			||||||
    if(connect(this->socketDescriptor, (const sockaddr *) remoteAddr, sizeof(sockaddr_in)) < 0){
 | 
					 | 
				
			||||||
        cerr << "Invalid connect" << endl;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    */
 | 
					 | 
				
			||||||
    if(bind(this->socketDescriptor, (const sockaddr *) localAdress, sizeof(sockaddr_in)) < 0) cout << "XXX" << endl;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    return true;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void FilteredUdpSocket::close() {
 | 
					 | 
				
			||||||
    if(this->socketDescriptor > 0) {
 | 
					 | 
				
			||||||
        shutdown(this->socketDescriptor, SHUT_RDWR);
 | 
					 | 
				
			||||||
        ::close(this->socketDescriptor);
 | 
					 | 
				
			||||||
        this->socketDescriptor = 0;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
ssize_t FilteredUdpSocket::write(const char *buffer, size_t size) {
 | 
					 | 
				
			||||||
    return sendto(this->socketDescriptor, buffer, size, 0, (const sockaddr *) this->remoteAdress, sizeof(sockaddr_in));
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
ssize_t FilteredUdpSocket::read(char *buffer, size_t size) {
 | 
					 | 
				
			||||||
    return recv(this->socketDescriptor, (void *) buffer, size, 0);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
@ -1,27 +0,0 @@
 | 
				
			|||||||
#pragma once
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#include <netinet/in.h>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
namespace ts {
 | 
					 | 
				
			||||||
    namespace connection {
 | 
					 | 
				
			||||||
        class FilteredUdpSocket {
 | 
					 | 
				
			||||||
            public:
 | 
					 | 
				
			||||||
                FilteredUdpSocket();
 | 
					 | 
				
			||||||
                ~FilteredUdpSocket();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                bool setup(sockaddr_in*);
 | 
					 | 
				
			||||||
                void close();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                ssize_t read(char* buffer, size_t size);
 | 
					 | 
				
			||||||
                ssize_t write(const char* buffer, size_t size);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                int getSocketDescriptor(){ return socketDescriptor; }
 | 
					 | 
				
			||||||
            private:
 | 
					 | 
				
			||||||
                int socketDescriptor;
 | 
					 | 
				
			||||||
                sockaddr_in* remoteAdress = nullptr;
 | 
					 | 
				
			||||||
                sockaddr_in* localAdress = nullptr;
 | 
					 | 
				
			||||||
        };
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        typedef FilteredUdpSocket UdpSocket;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
@ -1,151 +0,0 @@
 | 
				
			|||||||
//
 | 
					 | 
				
			||||||
// Created by wolverindev on 12.10.17.
 | 
					 | 
				
			||||||
//
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#include <iostream>
 | 
					 | 
				
			||||||
#include <cstring>
 | 
					 | 
				
			||||||
#include <ifaddrs.h>
 | 
					 | 
				
			||||||
#include <netinet/udp.h>   //Provides declarations for udp header
 | 
					 | 
				
			||||||
#include <netinet/ip.h>    //Provides declarations for ip header
 | 
					 | 
				
			||||||
#include <arpa/inet.h>
 | 
					 | 
				
			||||||
#include "RawUDPSocket.h"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
using namespace std;
 | 
					 | 
				
			||||||
using namespace ts::connection;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/*
 | 
					 | 
				
			||||||
    96 bit (12 bytes) pseudo header needed for udp header checksum calculation
 | 
					 | 
				
			||||||
*/
 | 
					 | 
				
			||||||
struct pseudo_header
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    u_int32_t source_address;
 | 
					 | 
				
			||||||
    u_int32_t dest_address;
 | 
					 | 
				
			||||||
    u_int8_t placeholder;
 | 
					 | 
				
			||||||
    u_int8_t protocol;
 | 
					 | 
				
			||||||
    u_int16_t udp_length;
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
RawUdpSocket::RawUdpSocket() {}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
RawUdpSocket::~RawUdpSocket() {}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
uint16_t RawUdpSocket::buildCheckSum(uint16_t* buffer, size_t size) {
 | 
					 | 
				
			||||||
    register long sum;
 | 
					 | 
				
			||||||
    unsigned short oddbyte;
 | 
					 | 
				
			||||||
    register short answer;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    sum = 0;
 | 
					 | 
				
			||||||
    while (size > 1) {
 | 
					 | 
				
			||||||
        sum += *buffer++;
 | 
					 | 
				
			||||||
        size -= 2;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    if (size == 1) {
 | 
					 | 
				
			||||||
        oddbyte = 0;
 | 
					 | 
				
			||||||
        *((u_char *) &oddbyte) = *(u_char *) buffer;
 | 
					 | 
				
			||||||
        sum += oddbyte;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    sum = (sum >> 16) + (sum & 0xffff);
 | 
					 | 
				
			||||||
    sum = sum + (sum >> 16);
 | 
					 | 
				
			||||||
    answer = (short) ~sum;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    return (answer);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
int RawUdpSocket::read(char *buffer, size_t size) {}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
int RawUdpSocket::write(const char *buffer, size_t size) {
 | 
					 | 
				
			||||||
    char datagram[4096];
 | 
					 | 
				
			||||||
    memset(datagram, 0, 4096);
 | 
					 | 
				
			||||||
    memcpy(&datagram[sizeof(iphdr) + sizeof(udphdr)], buffer, size);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    //IP header
 | 
					 | 
				
			||||||
    struct iphdr *iph = (struct iphdr *) datagram;
 | 
					 | 
				
			||||||
    //UDP header
 | 
					 | 
				
			||||||
    struct udphdr *udph = (struct udphdr *) (datagram + sizeof(struct ip));
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    //Setup the ip header
 | 
					 | 
				
			||||||
    iph->ihl = 5;
 | 
					 | 
				
			||||||
    iph->version = 4;
 | 
					 | 
				
			||||||
    iph->tos = 0;
 | 
					 | 
				
			||||||
    iph->tot_len = sizeof(iphdr) + sizeof(udphdr) + size; //Total length
 | 
					 | 
				
			||||||
    iph->id = htonl(12); //TODO increase
 | 
					 | 
				
			||||||
    iph->frag_off = 0;
 | 
					 | 
				
			||||||
    iph->ttl = 255; //Max 255 hops maybe change it to default 64
 | 
					 | 
				
			||||||
    iph->protocol = IPPROTO_UDP;
 | 
					 | 
				
			||||||
    iph->saddr = localAdress->sin_addr.s_addr;
 | 
					 | 
				
			||||||
    iph->daddr = remoteAdress->sin_addr.s_addr;
 | 
					 | 
				
			||||||
    iph->check = this->buildCheckSum ((unsigned short *) datagram, iph->tot_len);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    udph->source = localAdress->sin_port;
 | 
					 | 
				
			||||||
    udph->dest = remoteAdress->sin_port;
 | 
					 | 
				
			||||||
    udph->len = htons(8 + size);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    size_t csumLength = sizeof(struct pseudo_header) + sizeof(struct udphdr) + size;
 | 
					 | 
				
			||||||
    char csumData[csumLength];
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    pseudo_header psh;
 | 
					 | 
				
			||||||
    //Now the UDP checksum using the pseudo header
 | 
					 | 
				
			||||||
    psh.source_address = localAdress->sin_addr.s_addr;
 | 
					 | 
				
			||||||
    psh.dest_address = remoteAdress->sin_addr.s_addr;
 | 
					 | 
				
			||||||
    psh.placeholder = 0;
 | 
					 | 
				
			||||||
    psh.protocol = IPPROTO_UDP;
 | 
					 | 
				
			||||||
    psh.udp_length = htons(sizeof(struct udphdr) + size);
 | 
					 | 
				
			||||||
    memcpy(csumData , (char*) &psh , sizeof (struct pseudo_header));
 | 
					 | 
				
			||||||
    memcpy(csumData + sizeof(struct pseudo_header) , udph , sizeof(struct udphdr) + size);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    udph->check = buildCheckSum((uint16_t *) csumData, csumLength);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    auto written = sendto(this->socketDescriptor, datagram, iph->tot_len, 0, (struct sockaddr *) this->remoteAdress, sizeof(sockaddr));
 | 
					 | 
				
			||||||
    if(written != iph->tot_len){
 | 
					 | 
				
			||||||
        cerr << "Invalid write: " << written << endl;
 | 
					 | 
				
			||||||
        return -1;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    cout << "Write: " << written << endl;
 | 
					 | 
				
			||||||
    return size;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
bool RawUdpSocket::setup(sockaddr_in *remoteAdress) {
 | 
					 | 
				
			||||||
    this->remoteAdress = new sockaddr_in;
 | 
					 | 
				
			||||||
    memcpy(this->remoteAdress, remoteAdress, sizeof(sockaddr_in));
 | 
					 | 
				
			||||||
    this->socketDescriptor = socket(AF_INET, SOCK_RAW, IPPROTO_RAW);
 | 
					 | 
				
			||||||
    if(this->socketDescriptor < 0){
 | 
					 | 
				
			||||||
        if(this->socketDescriptor == EPERM){
 | 
					 | 
				
			||||||
            cerr << "Invalid permission. Dont have permission to create a new RAW socket!";
 | 
					 | 
				
			||||||
            return false;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        cerr << "Invalid socket create: " << errno << " - " << this->socketDescriptor << " -> " << strerror(errno) << endl;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    //get local addr
 | 
					 | 
				
			||||||
    this->localAdress = new sockaddr_in;
 | 
					 | 
				
			||||||
    struct ifaddrs *ifAddrStruct = NULL;
 | 
					 | 
				
			||||||
    getifaddrs(&ifAddrStruct);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    for (ifaddrs* ifa = ifAddrStruct; ifa != NULL; ifa = ifa->ifa_next) {
 | 
					 | 
				
			||||||
        if (!ifa->ifa_addr) {
 | 
					 | 
				
			||||||
            continue;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        if (ifa->ifa_addr->sa_family == AF_INET) { // check it is IP4
 | 
					 | 
				
			||||||
            // is a valid IP4 Address
 | 
					 | 
				
			||||||
            memcpy(this->localAdress, ifa->ifa_addr, sizeof(sockaddr_in));
 | 
					 | 
				
			||||||
            /*
 | 
					 | 
				
			||||||
            tmpAddrPtr=&((struct sockaddr_in *)ifa->ifa_addr)->sin_addr;
 | 
					 | 
				
			||||||
            char addressBuffer[INET_ADDRSTRLEN];
 | 
					 | 
				
			||||||
            inet_ntop(AF_INET, tmpAddrPtr, addressBuffer, INET_ADDRSTRLEN);
 | 
					 | 
				
			||||||
             */
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        /*
 | 
					 | 
				
			||||||
        else if (ifa->ifa_addr->sa_family == AF_INET6) { // check it is IP6
 | 
					 | 
				
			||||||
            // is a valid IP6 Address
 | 
					 | 
				
			||||||
            tmpAddrPtr=&((struct sockaddr_in6 *)ifa->ifa_addr)->sin6_addr;
 | 
					 | 
				
			||||||
            char addressBuffer[INET6_ADDRSTRLEN];
 | 
					 | 
				
			||||||
            inet_ntop(AF_INET6, tmpAddrPtr, addressBuffer, INET6_ADDRSTRLEN);
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
         */
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    if (ifAddrStruct != NULL) freeifaddrs(ifAddrStruct);
 | 
					 | 
				
			||||||
    this->localAdress->sin_port = 1232;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    return true;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
@ -1,28 +0,0 @@
 | 
				
			|||||||
#pragma once
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#include <netinet/in.h>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
namespace ts {
 | 
					 | 
				
			||||||
    namespace connection {
 | 
					 | 
				
			||||||
        class RawUdpSocket {
 | 
					 | 
				
			||||||
            public:
 | 
					 | 
				
			||||||
                RawUdpSocket();
 | 
					 | 
				
			||||||
                ~RawUdpSocket();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                bool setup(sockaddr_in*);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                int read(char* buffer, size_t size);
 | 
					 | 
				
			||||||
                int write(const char* buffer, size_t size);
 | 
					 | 
				
			||||||
                uint16_t buildCheckSum(uint16_t* buffer, size_t size);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                int getSocketDescriptor(){ return socketDescriptor; }
 | 
					 | 
				
			||||||
            private:
 | 
					 | 
				
			||||||
                int socketDescriptor;
 | 
					 | 
				
			||||||
                sockaddr_in* remoteAdress = nullptr;
 | 
					 | 
				
			||||||
                sockaddr_in* localAdress = nullptr;
 | 
					 | 
				
			||||||
        };
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        typedef RawUdpSocket UdpSocket;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
@ -1,25 +0,0 @@
 | 
				
			|||||||
cmake_minimum_required(VERSION 3.6)
 | 
					 | 
				
			||||||
project(TeamSpeak)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
include_directories(../shared/src)
 | 
					 | 
				
			||||||
add_definitions(-DLTM_DESC)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
set(SOURCE_FILES
 | 
					 | 
				
			||||||
		main.cpp
 | 
					 | 
				
			||||||
		src/ProxiedClient.cpp
 | 
					 | 
				
			||||||
		src/PorxiedClientSock5.cpp
 | 
					 | 
				
			||||||
		src/TSClient.cpp
 | 
					 | 
				
			||||||
)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
add_executable(TeamSpeakFloodClient ${SOURCE_FILES})
 | 
					 | 
				
			||||||
target_link_libraries(TeamSpeakFloodClient
 | 
					 | 
				
			||||||
		TeaSpeak
 | 
					 | 
				
			||||||
		pthread ThreadPool
 | 
					 | 
				
			||||||
		${TOM_LIBRARIES}
 | 
					 | 
				
			||||||
		crypto
 | 
					 | 
				
			||||||
		event
 | 
					 | 
				
			||||||
		event_pthreads
 | 
					 | 
				
			||||||
		/usr/local/lib/libjsoncpp.so
 | 
					 | 
				
			||||||
)
 | 
					 | 
				
			||||||
@ -1,81 +0,0 @@
 | 
				
			|||||||
#include <arpa/inet.h>
 | 
					 | 
				
			||||||
#include <string>
 | 
					 | 
				
			||||||
#include <cstring>
 | 
					 | 
				
			||||||
#include <src/ProxiedClient.h>
 | 
					 | 
				
			||||||
#include <event2/thread.h>
 | 
					 | 
				
			||||||
#include <iomanip>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
using namespace std;
 | 
					 | 
				
			||||||
using namespace ts::flood;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void hexout(std::ostream& os, unsigned char c)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    unsigned char uc = static_cast<unsigned char>(c);
 | 
					 | 
				
			||||||
    os << std::setw(2) << std::setfill('0') << (unsigned int)uc << ' ';
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void hexdump(std::ostream& outs, const std::string& s, size_t line_len = 16)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    std::ostringstream os;
 | 
					 | 
				
			||||||
    const std::string::size_type slen(s.size());
 | 
					 | 
				
			||||||
    int i(0);
 | 
					 | 
				
			||||||
    std::string::size_type pos(0);
 | 
					 | 
				
			||||||
    const std::streamsize lines(slen / line_len);
 | 
					 | 
				
			||||||
    const std::streamsize chars(slen % line_len);
 | 
					 | 
				
			||||||
    std::ios::fmtflags f(os.flags());
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    os << "Length: " << s.length() << "/" << std::hex << "0x" << s.length() << endl;
 | 
					 | 
				
			||||||
    for(std::streamsize line = 0; line <= lines - (chars  == 0 ? 1 : 0); ++line)
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        os << std::hex << setfill('0') << setw(3) << line * line_len << " | ";
 | 
					 | 
				
			||||||
        for(i = 0; i < line_len; ++i)
 | 
					 | 
				
			||||||
        {
 | 
					 | 
				
			||||||
            if(pos < s.length())
 | 
					 | 
				
			||||||
                hexout(os, s[pos]);
 | 
					 | 
				
			||||||
            else os << "   ";
 | 
					 | 
				
			||||||
            pos++;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        os << " | ";
 | 
					 | 
				
			||||||
        if(pos - line_len < s.length()){
 | 
					 | 
				
			||||||
            auto av = s.substr(pos - line_len);
 | 
					 | 
				
			||||||
            for(char c : av.substr(0, min(av.length(), line_len))){
 | 
					 | 
				
			||||||
                if(isprint(c))
 | 
					 | 
				
			||||||
                    os << c << " ";
 | 
					 | 
				
			||||||
                else
 | 
					 | 
				
			||||||
                    os << "." << " ";
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        os << '\n';
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    os.flags(f);
 | 
					 | 
				
			||||||
    outs << os.str() << endl;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
int main(int argc, char** argv){
 | 
					 | 
				
			||||||
    sockaddr_in remoteAddress{}, proxyAddress{};
 | 
					 | 
				
			||||||
    memset(&remoteAddress, 0, sizeof(remoteAddress));
 | 
					 | 
				
			||||||
    memset(&proxyAddress, 0, sizeof(proxyAddress));
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    proxyAddress.sin_family = AF_INET;
 | 
					 | 
				
			||||||
    proxyAddress.sin_port = htons(1085);
 | 
					 | 
				
			||||||
    proxyAddress.sin_addr.s_addr = inet_addr("185.89.100.17");
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    /*
 | 
					 | 
				
			||||||
    proxyAddress.sin_family = AF_INET;
 | 
					 | 
				
			||||||
    proxyAddress.sin_port = htons(1080);
 | 
					 | 
				
			||||||
    proxyAddress.sin_addr.s_addr = inet_addr("54.38.22.7");
 | 
					 | 
				
			||||||
    */
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    remoteAddress.sin_family = AF_INET;
 | 
					 | 
				
			||||||
    remoteAddress.sin_port = htons(1100);
 | 
					 | 
				
			||||||
    remoteAddress.sin_addr.s_addr = inet_addr("87.106.252.164");
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    assert(evthread_use_pthreads() == 0);
 | 
					 | 
				
			||||||
    event_base* evBase = event_base_new();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    ProxiedClient client(evBase, proxyAddress, remoteAddress);
 | 
					 | 
				
			||||||
    client.connect();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    event_base_dispatch(evBase);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
@ -1,111 +0,0 @@
 | 
				
			|||||||
#include <mutex>
 | 
					 | 
				
			||||||
#include <arpa/inet.h>
 | 
					 | 
				
			||||||
#include <ThreadPool/Thread.h>
 | 
					 | 
				
			||||||
#include "ProxiedClient.h"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
using namespace std;
 | 
					 | 
				
			||||||
using namespace std::chrono;
 | 
					 | 
				
			||||||
using namespace ts::flood;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#define CERROR(msg) \
 | 
					 | 
				
			||||||
do { \
 | 
					 | 
				
			||||||
    cerr << msg << endl;\
 | 
					 | 
				
			||||||
    this->disconnect();\
 | 
					 | 
				
			||||||
    return;\
 | 
					 | 
				
			||||||
} while(0)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static int port = 10000;
 | 
					 | 
				
			||||||
static threads::Mutex portLock;
 | 
					 | 
				
			||||||
void ProxiedClient::handleProxyMessage(const std::string &msg) {
 | 
					 | 
				
			||||||
    if(this->state == PROXY_INIT_METHODS){
 | 
					 | 
				
			||||||
        if(msg[0] != 0x05) CERROR("Invalid proxy version response (methode exchange)");
 | 
					 | 
				
			||||||
        if(msg[1] != 0x00) CERROR("Invalid respond methode");
 | 
					 | 
				
			||||||
        this->state = PROXY_INIT_CONNECTION;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        char buffer[128];
 | 
					 | 
				
			||||||
        int index = 0;
 | 
					 | 
				
			||||||
        buffer[index++] = 0x05; //Version
 | 
					 | 
				
			||||||
        buffer[index++] = 0x03; //Udp weiterleitung
 | 
					 | 
				
			||||||
        buffer[index++] = 0x00; //Resv
 | 
					 | 
				
			||||||
        buffer[index++] = 0x01; //Addr type = IPv4
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        auto addr = IPv4{this->remoteAddr->sin_addr.s_addr};
 | 
					 | 
				
			||||||
        buffer[index++] = addr._1;
 | 
					 | 
				
			||||||
        buffer[index++] = addr._2;
 | 
					 | 
				
			||||||
        buffer[index++] = addr._3;
 | 
					 | 
				
			||||||
        buffer[index++] = addr._4;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        buffer[index++] = (ntohs(this->remoteAddr->sin_port) >> 8) & 0xFF;
 | 
					 | 
				
			||||||
        buffer[index++] = (ntohs(this->remoteAddr->sin_port) >> 0) & 0xFF;
 | 
					 | 
				
			||||||
        this->sendMessage(string(buffer, index));
 | 
					 | 
				
			||||||
    } else if(this->state = PROXY_INIT_CONNECTION){
 | 
					 | 
				
			||||||
        cout << "res!" << endl;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        int index = 0;
 | 
					 | 
				
			||||||
        if(msg[index++] != 0x05) CERROR("Invalid proxy version response (connection request)");
 | 
					 | 
				
			||||||
        if(msg[index++] != 0x00) CERROR("Could not create connection (" + to_string((int) msg[1]) + ")");
 | 
					 | 
				
			||||||
        if(msg[index++] != 0x00) CERROR("Invalid proxy rsv response (connection request)");
 | 
					 | 
				
			||||||
        if(msg[index++] != 0x01) CERROR("Invalid proxy ip response type");
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        auto rAddr = IPv4{};
 | 
					 | 
				
			||||||
        rAddr._1 = msg[index++];
 | 
					 | 
				
			||||||
        rAddr._2 = msg[index++];
 | 
					 | 
				
			||||||
        rAddr._3 = msg[index++];
 | 
					 | 
				
			||||||
        rAddr._4 = msg[index++];
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        uint16_t pHigh = ((uint16_t) msg[index++]) & 0xFF;
 | 
					 | 
				
			||||||
        uint16_t pLow  = ((uint16_t) msg[index++]) & 0xFF;
 | 
					 | 
				
			||||||
        uint16_t rPort = (pHigh << 8) | pLow;
 | 
					 | 
				
			||||||
        cout << "Got udp relay " << rAddr.string() << ":" << rPort << endl;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        //Delete old connection
 | 
					 | 
				
			||||||
        //shutdown(this->fileDescriptor, SHUT_RDWR);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        event_del(this->wEvent);
 | 
					 | 
				
			||||||
        event_del(this->rEvent);
 | 
					 | 
				
			||||||
        this->fileDescriptor = 0;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        //Setup relay
 | 
					 | 
				
			||||||
        this->relayAddr = new sockaddr_in{};
 | 
					 | 
				
			||||||
        memset(relayAddr, 0, sizeof(*relayAddr));
 | 
					 | 
				
			||||||
        relayAddr->sin_family = AF_INET;
 | 
					 | 
				
			||||||
        relayAddr->sin_port = htons(rPort);
 | 
					 | 
				
			||||||
        relayAddr->sin_addr.s_addr = rAddr.addr;
 | 
					 | 
				
			||||||
        cout << "Relay addr: " << inet_ntoa(relayAddr->sin_addr) << ":" << ntohs(relayAddr->sin_port) << endl;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        this->localAddr = new sockaddr_in{};
 | 
					 | 
				
			||||||
        memset(localAddr, 0, sizeof(*localAddr));
 | 
					 | 
				
			||||||
        localAddr->sin_family = AF_INET;
 | 
					 | 
				
			||||||
        {
 | 
					 | 
				
			||||||
            lock_guard<threads::Mutex> l(portLock);
 | 
					 | 
				
			||||||
            localAddr->sin_port = this->remoteAddr->sin_port; // = htons(10000 + (port++ % 30000));
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        localAddr->sin_addr.s_addr = htonl(INADDR_ANY);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        this->fileDescriptor = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
 | 
					 | 
				
			||||||
        cout << "fd -> " << this->fileDescriptor << endl;
 | 
					 | 
				
			||||||
        int allow = 1;
 | 
					 | 
				
			||||||
        if(setsockopt(this->fileDescriptor, SOL_SOCKET, SO_REUSEADDR, &allow, sizeof(int)) < 0) CERROR("Could not enable reuse addr");
 | 
					 | 
				
			||||||
        if(bind(this->fileDescriptor, reinterpret_cast<const sockaddr *>(this->localAddr), sizeof(*this->localAddr)) < 0) CERROR("Could nto bind to relay");
 | 
					 | 
				
			||||||
        cout << "Bind on " << inet_ntoa(this->localAddr->sin_addr) << ":" << ntohs(this->localAddr->sin_port) << endl;
 | 
					 | 
				
			||||||
        this->state = PROXY_CONNECTED;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        this->rEvent = event_new(this->evBase, this->fileDescriptor, EV_READ | EV_PERSIST, ProxiedClient::handleEventRead, this);
 | 
					 | 
				
			||||||
        this->wEvent = event_new(this->evBase, this->fileDescriptor, EV_WRITE, ProxiedClient::handleEventWrite, this);
 | 
					 | 
				
			||||||
        event_add(rEvent, nullptr);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        threads::Thread([&](){
 | 
					 | 
				
			||||||
            threads::self::sleep_for(seconds(1));
 | 
					 | 
				
			||||||
            this->proxyInizalisized();
 | 
					 | 
				
			||||||
        });
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void ProxiedClient::requestProxyConnection() {
 | 
					 | 
				
			||||||
    char buffer[3];
 | 
					 | 
				
			||||||
    buffer[0] = 0x05; //Version
 | 
					 | 
				
			||||||
    buffer[1] = 1; //One methode
 | 
					 | 
				
			||||||
    buffer[2] = 0x00; //No auth required
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    this->sendMessage(string(buffer, 3));
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
@ -1,175 +0,0 @@
 | 
				
			|||||||
#include <mutex>
 | 
					 | 
				
			||||||
#include <netinet/tcp.h>
 | 
					 | 
				
			||||||
#include <arpa/inet.h>
 | 
					 | 
				
			||||||
#include "ProxiedClient.h"
 | 
					 | 
				
			||||||
#include "TSClient.h"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
using namespace std;
 | 
					 | 
				
			||||||
using namespace ts::flood;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
ProxiedClient::ProxiedClient(event_base* base, const sockaddr_in &proxyAddr, const sockaddr_in &remoteAddr) : evBase(base) {
 | 
					 | 
				
			||||||
    this->proxyAddr = new sockaddr_in{};
 | 
					 | 
				
			||||||
    this->remoteAddr = new sockaddr_in{};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    memcpy(this->proxyAddr, &proxyAddr, sizeof(proxyAddr));
 | 
					 | 
				
			||||||
    memcpy(this->remoteAddr, &remoteAddr, sizeof(proxyAddr));
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    this->client = new TSClient(this);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
ProxiedClient::~ProxiedClient() {
 | 
					 | 
				
			||||||
    delete this->proxyAddr;
 | 
					 | 
				
			||||||
    delete this->remoteAddr;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#define CERR(msg) \
 | 
					 | 
				
			||||||
do { \
 | 
					 | 
				
			||||||
    cerr << "Could not connect: " << msg << "(" << errno << "/" << strerror(errno) << ")" << endl; \
 | 
					 | 
				
			||||||
    return false; \
 | 
					 | 
				
			||||||
} while(0)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#if defined(TCP_CORK) && !defined(TCP_NOPUSH)
 | 
					 | 
				
			||||||
    #define TCP_NOPUSH TCP_CORK
 | 
					 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static int enabled = 1;
 | 
					 | 
				
			||||||
static int disabled = 0;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
bool ProxiedClient::connect() {
 | 
					 | 
				
			||||||
    assert(this->state == ProxyState::PROXY_UNCONNECTED);
 | 
					 | 
				
			||||||
    TAILQ_INIT(&this->writeQueue);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    this->fileDescriptor = socket(AF_INET, SOCK_STREAM, 0);
 | 
					 | 
				
			||||||
    if(this->fileDescriptor < 0) CERR("Socket setup failed");
 | 
					 | 
				
			||||||
    if(::connect(this->fileDescriptor, reinterpret_cast<const sockaddr *>(this->proxyAddr), sizeof(*this->proxyAddr)) < 0) CERR("connect() failed");
 | 
					 | 
				
			||||||
    if(setsockopt(this->fileDescriptor, SOL_SOCKET, SO_REUSEADDR, &enabled, sizeof(enabled)) < 0) CERR("could not set reuse addr");
 | 
					 | 
				
			||||||
    if(setsockopt(this->fileDescriptor, IPPROTO_TCP, TCP_NOPUSH, &disabled, sizeof(disabled)) < 0) CERR("could not set no push");
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    cout << "Connected to " << inet_ntoa(this->proxyAddr->sin_addr) << endl;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    this->rEvent = event_new(this->evBase, this->fileDescriptor, EV_READ | EV_PERSIST, ProxiedClient::handleEventRead, this);
 | 
					 | 
				
			||||||
    this->wEvent = event_new(this->evBase, this->fileDescriptor, EV_WRITE, ProxiedClient::handleEventWrite, this);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    event_add(rEvent, nullptr);
 | 
					 | 
				
			||||||
    this->state = ProxyState::PROXY_INIT_METHODS;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    this->requestProxyConnection();
 | 
					 | 
				
			||||||
    return true;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void ProxiedClient::disconnect() {
 | 
					 | 
				
			||||||
    this->closeConnection();
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void ProxiedClient::closeConnection() {
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        lock_guard<threads::Mutex> lock(this->stateLock);
 | 
					 | 
				
			||||||
        if(this->state == PROXY_UNCONNECTED) return;
 | 
					 | 
				
			||||||
        this->state = PROXY_UNCONNECTED;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    event_del(this->wEvent);
 | 
					 | 
				
			||||||
    event_del(this->rEvent);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    this->wEvent = nullptr;
 | 
					 | 
				
			||||||
    this->rEvent = nullptr;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void ProxiedClient::sendMessage(const std::string& message) {
 | 
					 | 
				
			||||||
    buffer::RawBuffer* buffer;
 | 
					 | 
				
			||||||
    if(this->state != PROXY_CONNECTED){
 | 
					 | 
				
			||||||
        buffer = new buffer::RawBuffer{message.length()};
 | 
					 | 
				
			||||||
        memcpy(buffer->buffer, message.data(), message.length());
 | 
					 | 
				
			||||||
    } else {
 | 
					 | 
				
			||||||
        cout << "Send " << message.length() << " bytes with relay" << endl;
 | 
					 | 
				
			||||||
        int relayHeaderLength = 2 + 1 + 1 + 4 + 2;
 | 
					 | 
				
			||||||
        buffer = new buffer::RawBuffer{relayHeaderLength + message.length()};
 | 
					 | 
				
			||||||
        buffer->index = 0;
 | 
					 | 
				
			||||||
        char preBuffer[relayHeaderLength];
 | 
					 | 
				
			||||||
        preBuffer[0] = 0x00;
 | 
					 | 
				
			||||||
        preBuffer[1] = 0x00;
 | 
					 | 
				
			||||||
        preBuffer[2] = 0x00;
 | 
					 | 
				
			||||||
        preBuffer[3] = 0x01;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        IPv4 addr{this->relayAddr->sin_addr.s_addr};
 | 
					 | 
				
			||||||
        preBuffer[4] = addr._1;
 | 
					 | 
				
			||||||
        preBuffer[5] = addr._2;
 | 
					 | 
				
			||||||
        preBuffer[6] = addr._3;
 | 
					 | 
				
			||||||
        preBuffer[7] = addr._4;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        preBuffer[8] = (ntohs(this->relayAddr->sin_port) >> 8) & 0xFF;
 | 
					 | 
				
			||||||
        preBuffer[9] = (ntohs(this->relayAddr->sin_port) >> 0) & 0xFF;
 | 
					 | 
				
			||||||
        //memset(&preBuffer[4], 0, 6);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        memcpy(&buffer->buffer[0], preBuffer, relayHeaderLength);
 | 
					 | 
				
			||||||
        memcpy(&buffer->buffer[relayHeaderLength], message.data(), message.length());
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        lock_guard<threads::Mutex> lock(this->queueLock);
 | 
					 | 
				
			||||||
        TAILQ_INSERT_TAIL(&this->writeQueue, buffer, tail);
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    event_add(this->wEvent, nullptr);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void ProxiedClient::handleMessage(const std::string &message) {
 | 
					 | 
				
			||||||
    if(this->state == PROXY_UNCONNECTED) return;
 | 
					 | 
				
			||||||
    if(this->state == PROXY_CONNECTED) return; //TODO
 | 
					 | 
				
			||||||
    this->handleProxyMessage(message);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
extern void hexdump(std::ostream& outs, const std::string& s, size_t line_len = 16);
 | 
					 | 
				
			||||||
void ProxiedClient::handleEventWrite(int fd, short, void* ptrClient) {
 | 
					 | 
				
			||||||
    auto* client = static_cast<ProxiedClient *>(ptrClient);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    buffer::RawBuffer* buffer = nullptr;
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        lock_guard<threads::Mutex> lock(client->queueLock);
 | 
					 | 
				
			||||||
        buffer = TAILQ_FIRST(&client->writeQueue);
 | 
					 | 
				
			||||||
        if(!buffer) return;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        ssize_t writtenBytes = 0;
 | 
					 | 
				
			||||||
        if(client->state == PROXY_CONNECTED){
 | 
					 | 
				
			||||||
            cout << "Write bytes to relay - " << fd << " - " << inet_ntoa(client->relayAddr->sin_addr) << ":" << ntohs(client->relayAddr->sin_port) << endl;
 | 
					 | 
				
			||||||
            hexdump(cout, string((const char*) buffer->buffer, buffer->length));
 | 
					 | 
				
			||||||
            writtenBytes = sendto(fd, buffer->buffer, buffer->length, 0, (const sockaddr *) client->relayAddr, sizeof(*client->relayAddr));
 | 
					 | 
				
			||||||
        } else
 | 
					 | 
				
			||||||
            writtenBytes = send(fd, &buffer->buffer[buffer->index], buffer->length - buffer->index, 0);
 | 
					 | 
				
			||||||
        buffer->index += writtenBytes;
 | 
					 | 
				
			||||||
        cout << "Written: " << writtenBytes << endl;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        if(buffer->index >= buffer->length || client->state == PROXY_CONNECTED) {
 | 
					 | 
				
			||||||
            TAILQ_REMOVE(&client->writeQueue, buffer, tail);
 | 
					 | 
				
			||||||
            delete buffer;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        if(!TAILQ_EMPTY(&client->writeQueue))
 | 
					 | 
				
			||||||
            event_add(client->wEvent, nullptr);
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void ProxiedClient::handleEventRead(int fd, short, void* ptrClient) {
 | 
					 | 
				
			||||||
    auto* client = static_cast<ProxiedClient *>(ptrClient);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    char buffer[1024];
 | 
					 | 
				
			||||||
    sockaddr_in remoteAddr{};
 | 
					 | 
				
			||||||
    socklen_t remoteAddrSize = sizeof(remoteAddr);
 | 
					 | 
				
			||||||
    auto read = recvfrom(fd, buffer, 1024, MSG_DONTWAIT, reinterpret_cast<sockaddr *>(&remoteAddr), &remoteAddrSize);
 | 
					 | 
				
			||||||
    cout << "Read " << read << " bytes" << endl;
 | 
					 | 
				
			||||||
    if(read < 0){
 | 
					 | 
				
			||||||
        if(errno == EWOULDBLOCK) return;
 | 
					 | 
				
			||||||
        cerr << "Invalid read: " << errno << "/" << strerror(errno) << endl;
 | 
					 | 
				
			||||||
        client->disconnect();
 | 
					 | 
				
			||||||
        return;
 | 
					 | 
				
			||||||
    } else if(read == 0){
 | 
					 | 
				
			||||||
        cerr << "Client hangs up!" << endl;
 | 
					 | 
				
			||||||
        client->closeConnection();
 | 
					 | 
				
			||||||
        return;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    hexdump(cout, string(buffer, read));
 | 
					 | 
				
			||||||
    client->handleMessage(string(buffer, read));
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void ProxiedClient::proxyInizalisized() {
 | 
					 | 
				
			||||||
    this->client->startConnect();
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
@ -1,72 +0,0 @@
 | 
				
			|||||||
#pragma once
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#include <string>
 | 
					 | 
				
			||||||
#include <netinet/in.h>
 | 
					 | 
				
			||||||
#include <misc/queue.h>
 | 
					 | 
				
			||||||
#include <protocol/buffers.h>
 | 
					 | 
				
			||||||
#include <event.h>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
namespace ts {
 | 
					 | 
				
			||||||
    namespace flood {
 | 
					 | 
				
			||||||
        union IPv4 {
 | 
					 | 
				
			||||||
            uint32_t addr;
 | 
					 | 
				
			||||||
            struct __attribute__ ((__packed__)) {
 | 
					 | 
				
			||||||
                uint8_t _1;
 | 
					 | 
				
			||||||
                uint8_t _2;
 | 
					 | 
				
			||||||
                uint8_t _3;
 | 
					 | 
				
			||||||
                uint8_t _4;
 | 
					 | 
				
			||||||
            };
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            inline std::string string(){
 | 
					 | 
				
			||||||
                std::stringstream ss;
 | 
					 | 
				
			||||||
                ss  << (int) _1 << "." << (int) _2 << "." << (int) _3 << "." << (int) _4;
 | 
					 | 
				
			||||||
                return ss.str();
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
        };
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        class TSClient;
 | 
					 | 
				
			||||||
        enum ProxyState {
 | 
					 | 
				
			||||||
            PROXY_UNCONNECTED,
 | 
					 | 
				
			||||||
            PROXY_INIT_METHODS,
 | 
					 | 
				
			||||||
            PROXY_INIT_CONNECTION,
 | 
					 | 
				
			||||||
            PROXY_CONNECTED
 | 
					 | 
				
			||||||
        };
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        class ProxiedClient {
 | 
					 | 
				
			||||||
            public:
 | 
					 | 
				
			||||||
                ProxiedClient(event_base*,const sockaddr_in& proxyAddr, const sockaddr_in& remoteAddr);
 | 
					 | 
				
			||||||
                ~ProxiedClient();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                bool connect();
 | 
					 | 
				
			||||||
                void disconnect();
 | 
					 | 
				
			||||||
                void closeConnection();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                void handleMessage(const std::string& message);
 | 
					 | 
				
			||||||
                void sendMessage(const std::string &);
 | 
					 | 
				
			||||||
            private:
 | 
					 | 
				
			||||||
                static void handleEventRead(int, short, void*);
 | 
					 | 
				
			||||||
                static void handleEventWrite(int, short, void*);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                void requestProxyConnection();
 | 
					 | 
				
			||||||
                void handleProxyMessage(const std::string &);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                void proxyInizalisized();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                event_base* evBase = nullptr;
 | 
					 | 
				
			||||||
                event* rEvent = nullptr;
 | 
					 | 
				
			||||||
                event* wEvent = nullptr;
 | 
					 | 
				
			||||||
                int fileDescriptor;
 | 
					 | 
				
			||||||
                ProxyState state = ProxyState::PROXY_UNCONNECTED;
 | 
					 | 
				
			||||||
                threads::Mutex stateLock;
 | 
					 | 
				
			||||||
                sockaddr_in* proxyAddr = nullptr;
 | 
					 | 
				
			||||||
                sockaddr_in* relayAddr = nullptr;
 | 
					 | 
				
			||||||
                sockaddr_in* localAddr = nullptr;
 | 
					 | 
				
			||||||
                sockaddr_in* remoteAddr = nullptr;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                TAILQ_HEAD(, buffer::RawBuffer) writeQueue;
 | 
					 | 
				
			||||||
                threads::Mutex queueLock;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                TSClient* client = nullptr;
 | 
					 | 
				
			||||||
        };
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
@ -1,108 +0,0 @@
 | 
				
			|||||||
//
 | 
					 | 
				
			||||||
// Created by wolverindev on 06.01.18.
 | 
					 | 
				
			||||||
//
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#include "TSClient.h"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
using namespace std;
 | 
					 | 
				
			||||||
using namespace std::chrono;
 | 
					 | 
				
			||||||
using namespace ts::flood;
 | 
					 | 
				
			||||||
using namespace ts::protocol;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
TSClient::TSClient(ProxiedClient* con) : connection(con) {
 | 
					 | 
				
			||||||
    this->cryptionHandler = new connection::CryptionHandler();
 | 
					 | 
				
			||||||
    this->cryptionHandler->reset();
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
TSClient::~TSClient() {}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void TSClient::handleMessageRead(const std::string& message) {
 | 
					 | 
				
			||||||
    if(message.length() < MAC_SIZE + SERVER_HEADER_SIZE) {
 | 
					 | 
				
			||||||
        cerr << "Invalid pkt length!" << endl;
 | 
					 | 
				
			||||||
        return;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    shared_ptr<ServerPacket> packet = make_shared<ServerPacket>(message);
 | 
					 | 
				
			||||||
    cout << "Having packet " << packet->type().name() << endl;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void TSClient::sendPacket(ts::protocol::ClientPacket &packet, int32_t packetId) {
 | 
					 | 
				
			||||||
    size_t maxDataLength = 500 - packet.header().length();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    if(packet.data().length() > maxDataLength){
 | 
					 | 
				
			||||||
        cout << "Split packet" << endl;
 | 
					 | 
				
			||||||
        string error;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        /*
 | 
					 | 
				
			||||||
        if(!compressPacket(&packet, error)){
 | 
					 | 
				
			||||||
            cerr << "Compress error!" << endl;
 | 
					 | 
				
			||||||
            return;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        packet.enableFlag(PacketFlag::Compressed);
 | 
					 | 
				
			||||||
        */
 | 
					 | 
				
			||||||
        if(packet.data().length() > maxDataLength){
 | 
					 | 
				
			||||||
            std::vector<ClientPacket*> siblings;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            ClientPacket* root = new ClientPacket(packet.type(), packet.flagMask(), packet.data());
 | 
					 | 
				
			||||||
            root->enableFlag(PacketFlag::Fragmented);
 | 
					 | 
				
			||||||
            //assert(root->hasFlag(PacketFlag::Compressed));
 | 
					 | 
				
			||||||
            siblings.push_back(root);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            //Max len - mac - header
 | 
					 | 
				
			||||||
            while(siblings.back()->data().length() > maxDataLength){
 | 
					 | 
				
			||||||
                auto overhead = siblings.back()->data().substr(maxDataLength);
 | 
					 | 
				
			||||||
                siblings.back()->data(siblings.back()->data().substr(0, maxDataLength));
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                ClientPacket* sib = new ClientPacket(packet.type(), packet.flagMask(), overhead);
 | 
					 | 
				
			||||||
                sib->toggle(PacketFlag::Fragmented, false);
 | 
					 | 
				
			||||||
                siblings.push_back(sib);
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
            siblings.back()->enableFlag(PacketFlag::Fragmented);
 | 
					 | 
				
			||||||
            for(auto elm : siblings){
 | 
					 | 
				
			||||||
                sendPacket(*elm);
 | 
					 | 
				
			||||||
                delete elm;
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
            return;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    if (packetId == -1)
 | 
					 | 
				
			||||||
	    packet.applyPacketId(pktIdManager);
 | 
					 | 
				
			||||||
    else packet.applyPacketId((uint16_t) packetId, 0);
 | 
					 | 
				
			||||||
    packet.clientId(this->clientId);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    string error = "success";
 | 
					 | 
				
			||||||
    if (!this->cryptionHandler->progressPacketOut(&packet, error)) {
 | 
					 | 
				
			||||||
        cerr << "Invalid crypt -> " << error << endl;
 | 
					 | 
				
			||||||
        return;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    this->connection->sendMessage(packet.mac() + packet.header() + packet.data());
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
const int InitVersionLength = 4;
 | 
					 | 
				
			||||||
const uint8_t InitVersion[InitVersionLength] = {0x06, 0x3b, 0xEC, 0xE9};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void TSClient::startConnect() {
 | 
					 | 
				
			||||||
    int maxBufferSize = 512;
 | 
					 | 
				
			||||||
    size_t bufferIndex = 0;
 | 
					 | 
				
			||||||
    uint8_t buffer[maxBufferSize];
 | 
					 | 
				
			||||||
    string error = "success";
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    memcpy(buffer, InitVersion, InitVersionLength);
 | 
					 | 
				
			||||||
    bufferIndex += InitVersionLength;
 | 
					 | 
				
			||||||
    buffer[bufferIndex++] = 0x00; //Login state
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    int64_t millis = duration_cast<milliseconds>(system_clock::now().time_since_epoch()).count();
 | 
					 | 
				
			||||||
    memcpy(&buffer[5], &millis, 4);
 | 
					 | 
				
			||||||
    bufferIndex += 4;
 | 
					 | 
				
			||||||
    //generate the alpha key
 | 
					 | 
				
			||||||
    for (int i = 0; i < 4; i++) buffer[bufferIndex++] = (uint8_t) std::rand();
 | 
					 | 
				
			||||||
    bufferIndex += 8; //Reserved bytes
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    ClientPacket pkt(ts::protocol::PacketTypeInfo::Init1, string((char *) buffer, bufferIndex));
 | 
					 | 
				
			||||||
    pkt.clientId(0);
 | 
					 | 
				
			||||||
    pkt.toggle(ts::protocol::PacketFlag::Unencrypted, true);
 | 
					 | 
				
			||||||
    this->sendPacket(pkt, 101);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
@ -1,36 +0,0 @@
 | 
				
			|||||||
#pragma once
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#include "ProxiedClient.h"
 | 
					 | 
				
			||||||
#include <string>
 | 
					 | 
				
			||||||
#include <Definitions.h>
 | 
					 | 
				
			||||||
#include <protocol/CryptionHandler.h>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
namespace ts {
 | 
					 | 
				
			||||||
    namespace flood {
 | 
					 | 
				
			||||||
        enum TSClientConnectionState {
 | 
					 | 
				
			||||||
            TSC_UNCONNECTED,
 | 
					 | 
				
			||||||
            TSC_PRE,
 | 
					 | 
				
			||||||
            TSC_RSA,
 | 
					 | 
				
			||||||
            TSC_HIGH,
 | 
					 | 
				
			||||||
            TSC_CONNECTED
 | 
					 | 
				
			||||||
        };
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        class TSClient {
 | 
					 | 
				
			||||||
            public:
 | 
					 | 
				
			||||||
                TSClient(ProxiedClient*);
 | 
					 | 
				
			||||||
                ~TSClient();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                void startConnect();
 | 
					 | 
				
			||||||
                void handleMessageRead(const std::string&);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                void sendPacket(ts::protocol::ClientPacket &packet, int32_t packetId = -1);
 | 
					 | 
				
			||||||
            private:
 | 
					 | 
				
			||||||
                ProxiedClient* connection;
 | 
					 | 
				
			||||||
                TSClientConnectionState state = TSClientConnectionState::TSC_UNCONNECTED;
 | 
					 | 
				
			||||||
                protocol::PacketIdManager pktIdManager;
 | 
					 | 
				
			||||||
                ts::connection::CryptionHandler* cryptionHandler = nullptr;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                ClientId clientId = 0;
 | 
					 | 
				
			||||||
        };
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
@ -345,6 +345,19 @@ HWID_REGEX(ios, "^[A-Z0-9]{8}-[A-Z0-9]{4}-[A-Z0-9]{4}-[A-Z0-9]{4}-[A-Z0-9]{12}$"
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
CommandResult SpeakingClient::handleCommandClientInit(Command& cmd) {
 | 
					CommandResult SpeakingClient::handleCommandClientInit(Command& cmd) {
 | 
				
			||||||
	TIMING_START(timings);
 | 
						TIMING_START(timings);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        lock_guard<threads::Mutex> lock(this->server->join_attempts_lock);
 | 
				
			||||||
 | 
					        auto inetAddr = this->getPeerIp();
 | 
				
			||||||
 | 
					        if(config::voice::clientConnectLimit > 0 && this->server->join_attempts[inetAddr] + 1 > config::voice::clientConnectLimit)
 | 
				
			||||||
 | 
					            return {findError("client_is_flooding"), "To many joins per second per ip"};
 | 
				
			||||||
 | 
					        if(config::voice::connectLimit > 0 && this->server->join_attempts["_"] + 1 > config::voice::connectLimit)
 | 
				
			||||||
 | 
					            return {findError("client_is_flooding"), "To many joins per second"};
 | 
				
			||||||
 | 
					        this->server->join_attempts[inetAddr]++;
 | 
				
			||||||
 | 
					        this->server->join_attempts["_"]++;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    TIMING_STEP(timings, "join atmp c");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if(!DatabaseHelper::assignDatabaseId(this->server->getSql(), this->server->getServerId(), _this.lock())) return {findError("vs_critical"), "Could not assign database id!"};
 | 
						if(!DatabaseHelper::assignDatabaseId(this->server->getSql(), this->server->getServerId(), _this.lock())) return {findError("vs_critical"), "Could not assign database id!"};
 | 
				
			||||||
	TIMING_STEP(timings, "db assign  ");
 | 
						TIMING_STEP(timings, "db assign  ");
 | 
				
			||||||
	this->server->getGroupManager()->enableCache(this->getClientDatabaseId());
 | 
						this->server->getGroupManager()->enableCache(this->getClientDatabaseId());
 | 
				
			||||||
@ -427,18 +440,6 @@ CommandResult SpeakingClient::handleCommandClientInit(Command& cmd) {
 | 
				
			|||||||
	debugMessage(this->getServerId(), "{} Got client init. (HWID: {})", CLIENT_STR_LOG_PREFIX, this->getHardwareId());
 | 
						debugMessage(this->getServerId(), "{} Got client init. (HWID: {})", CLIENT_STR_LOG_PREFIX, this->getHardwareId());
 | 
				
			||||||
	TIMING_STEP(timings, "props apply");
 | 
						TIMING_STEP(timings, "props apply");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	{
 | 
					 | 
				
			||||||
		lock_guard<threads::Mutex> lock(this->server->join_attempts_lock);
 | 
					 | 
				
			||||||
		auto inetAddr = this->getPeerIp();
 | 
					 | 
				
			||||||
		if(config::voice::clientConnectLimit > 0 && this->server->join_attempts[inetAddr] + 1 > config::voice::clientConnectLimit)
 | 
					 | 
				
			||||||
			return {findError("client_is_flooding"), "To many joins per second per ip"};
 | 
					 | 
				
			||||||
		if(config::voice::connectLimit > 0 && this->server->join_attempts["_"] + 1 > config::voice::connectLimit)
 | 
					 | 
				
			||||||
			return {findError("client_is_flooding"), "To many joins per second"};
 | 
					 | 
				
			||||||
		this->server->join_attempts[inetAddr]++;
 | 
					 | 
				
			||||||
		this->server->join_attempts["_"]++;
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	TIMING_STEP(timings, "join atmp c");
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	auto permissions_list = this->permissionValues(permission::PERMTEST_ORDERED, {
 | 
						auto permissions_list = this->permissionValues(permission::PERMTEST_ORDERED, {
 | 
				
			||||||
			permission::b_virtualserver_join_ignore_password,
 | 
								permission::b_virtualserver_join_ignore_password,
 | 
				
			||||||
			permission::b_client_ignore_bans,
 | 
								permission::b_client_ignore_bans,
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user