From 553ba135c97e8db3ed9de3e9315d1668bb246393 Mon Sep 17 00:00:00 2001 From: spiralvoice Date: Sat, 23 Oct 2010 18:25:13 +0000 Subject: [PATCH] patch #7318 --- distrib/ChangeLog | 4 ++ src/daemon/common/commonGlobals.ml | 4 +- src/daemon/common/commonOptions.ml | 2 +- src/daemon/driver/driverCommands.ml | 25 ++++++-- src/networks/donkey/donkeyClient.ml | 102 +++++++++++++++++++++++++++++++ src/networks/donkey/donkeyProtoClient.ml | 76 +++++++++++++++++++---- src/networks/donkey/donkeyTypes.ml | 2 + 7 files changed, 195 insertions(+), 20 deletions(-) diff --git a/distrib/ChangeLog b/distrib/ChangeLog index bee7a9de..75b9cabd 100644 --- a/distrib/ChangeLog +++ b/distrib/ChangeLog @@ -15,6 +15,10 @@ ChangeLog ========= 2010/10/23 +7318: EDK: Emule captcha support and slight cleanup (dennisne) +- added support for Emule's anti-spam chat CAPTCHAs +- added clear_message_log command to clear (long) message logs +- HTML: reversed order of chat messages 7319: EDK: Fix CryptoPP on mips64 abi n32 (viric) 7356: options: ensure that tmp file is removed (ygrek) 7355: DC web ui: escape commands' arguments (ygrek) diff --git a/src/daemon/common/commonGlobals.ml b/src/daemon/common/commonGlobals.ml index 2a863f59..276ba08f 100644 --- a/src/daemon/common/commonGlobals.ml +++ b/src/daemon/common/commonGlobals.ml @@ -445,12 +445,12 @@ let chat_message_fifo = (Fifo.create () : (int * string * int * string * string) let log_chat_message i num n s = Fifo.put chat_message_fifo (last_time(),i,num,n,s); (try - Unix2.tryopen_write_gen !messages_log [Open_creat; Open_wronly; Open_append] + Unix2.tryopen_write_gen messages_log [Open_creat; Open_wronly; Open_append] 0o600 (fun oc -> Printf.fprintf oc "%s: %s (%s): %s\n" (Date.simple (BasicSocket.date_of_int (last_time ()))) n i s) with e -> lprintf_nl "[ERROR] Exception %s while trying to log message to %s" - (Printexc2.to_string e) !messages_log); + (Printexc2.to_string e) messages_log); while (Fifo.length chat_message_fifo) > !!html_mods_max_messages do ignore(Fifo.take chat_message_fifo) diff --git a/src/daemon/common/commonOptions.ml b/src/daemon/common/commonOptions.ml index 0bc6de54..16b3e8e0 100644 --- a/src/daemon/common/commonOptions.ml +++ b/src/daemon/common/commonOptions.ml @@ -303,7 +303,7 @@ let results_ini = create_options_file "results.ini" let files_ini = create_options_file "files.ini" let friends_ini = create_options_file "friends.ini" -let messages_log = ref "messages.log" +let messages_log = "messages.log" let servers_section = file_section servers_ini [] "" diff --git a/src/daemon/driver/driverCommands.ml b/src/daemon/driver/driverCommands.ml index fa70f9b9..bd1a9079 100644 --- a/src/daemon/driver/driverCommands.ml +++ b/src/daemon/driver/driverCommands.ml @@ -543,6 +543,11 @@ let _ = "" ), " :\t\t\tprint activity in the last minutes"; + "clear_message_log", Arg_none (fun o -> + Fifo.clear chat_message_fifo; + Printf.sprintf "Chat messages cleared" + ), ":\t\t\t\tclear chat message buffer"; + "message_log", Arg_multiple (fun args o -> let buf = o.conn_buf in html_mods_cntr_init (); @@ -577,7 +582,7 @@ let _ = ( "0", "srh", "Client name", "Client name" ) ; ( "0", "srh", "Message text", "Message" ) ] ; - Fifo.iter (fun (t,i,num,n,s) -> + List.iter (fun (t,i,num,n,s) -> if use_html_mods o then begin Printf.bprintf buf "\\" (html_mods_cntr ()); @@ -586,13 +591,15 @@ let _ = ("", "sr", i); ("", "sr", Printf.sprintf "%d" num); ("", "sr", n); - ("", "srw", (String.escaped s)) ]; + ("", "srw", (if String.length s > 11 && String.sub s 0 11 = "data:image/" then + "\\" + else String.escaped s)) ]; Printf.bprintf buf "\\" end else Printf.bprintf buf "\n%s [client #%d] %s(%s): %s\n" (Date.simple (BasicSocket.date_of_int t)) num n i s; - ) chat_message_fifo; + ) (List.rev (Fifo.to_list chat_message_fifo)); if use_html_mods o then Printf.bprintf buf "\\\\\\"; @@ -609,8 +616,10 @@ let _ = a1 ^ a2 ^ " " ) "" msglist in let cnum = int_of_string n in - client_say (client_find cnum) msg; - log_chat_message "localhost" 0 !!global_login msg; + let c = client_find cnum in + let g = client_info c in + client_say c msg; + log_chat_message "FROM ME" cnum ("TO: " ^ g.client_name) msg; Printf.sprintf "Sending msg to client #%d: %s" cnum msg; | _ -> if use_html_mods o then begin @@ -673,7 +682,11 @@ formID.msgText.value=\\\"\\\"; Printf.bprintf buf "\\
\\\\\\\\\\\\"; + Value=\\\"Refresh\\\"\\>\\\\"; + Printf.bprintf buf "\\ + \\\\\\\\\\\\"; "" end else diff --git a/src/networks/donkey/donkeyClient.ml b/src/networks/donkey/donkeyClient.ml index c8955c3e..e8962106 100644 --- a/src/networks/donkey/donkeyClient.ml +++ b/src/networks/donkey/donkeyClient.ml @@ -1960,6 +1960,108 @@ end else *) ) in log_chat_message cip (client_num c) c.client_name s; + + + | M.EmuleCaptchaReq t -> + let buf = Buffer.create 4096 in + let len = String.length t in + let b64_map = [| + 'A'; 'B'; 'C'; 'D'; 'E'; 'F'; 'G'; 'H'; 'I'; 'J'; 'K'; 'L'; 'M'; 'N'; 'O'; 'P'; + 'Q'; 'R'; 'S'; 'T'; 'U'; 'V'; 'W'; 'X'; 'Y'; 'Z'; 'a'; 'b'; 'c'; 'd'; 'e'; 'f'; + 'g'; 'h'; 'i'; 'j'; 'k'; 'l'; 'm'; 'n'; 'o'; 'p'; 'q'; 'r'; 's'; 't'; 'u'; 'v'; + 'w'; 'x'; 'y'; 'z'; '0'; '1'; '2'; '3'; '4'; '5'; '6'; '7'; '8'; '9'; '+'; '/'|] in + + for i = 0 to (len / 3) - 1 do + let c1 = int_of_char t.[i*3] in + let c2 = int_of_char t.[i*3+1] in + let c3 = int_of_char t.[i*3+2] in + let n1 = c1 lsr 2 in + let n2 = ((c1 land 3) lsl 4) lor (c2 lsr 4) in + let n3 = ((c2 land 0xf) lsl 2) lor (c3 lsr 6) in + let n4 = c3 land 63 in + Printf.bprintf buf "%c%c%c%c" b64_map.(n1) b64_map.(n2) b64_map.(n3) b64_map.(n4); + done; + if (len mod 3) = 1 then ( + let i = len - 2 in + let c1 = int_of_char t.[i] in + let c2 = int_of_char t.[i+1] in + let n1 = ((c1 land 0xf) lsl 2) lor (c2 lsr 6) in + let n2 = c2 land 63 in + Printf.bprintf buf "%c%c==" b64_map.(n1) b64_map.(n2) + ) + else if (len mod 3) = 2 then ( + let i = len - 3 in + let c1 = int_of_char t.[i] in + let c2 = int_of_char t.[i+1] in + let c3 = int_of_char t.[i+2] in + let n1 = ((c1 land 3) lsl 4) lor (c2 lsr 4) in + let n2 = ((c2 land 0xf) lsl 2) lor (c3 lsr 6) in + let n3 = c3 land 63 in + Printf.bprintf buf "%c%c%c=" b64_map.(n1) b64_map.(n2) b64_map.(n3) + ); + + let b64data = Buffer.contents buf in + let cip = + ( + try + + match c.client_source.DonkeySources.source_sock with + Connection sock -> + (Ip.to_string (peer_ip sock) ^ ":" ^ string_of_int (peer_port sock)) + | _ -> (match c.client_kind with + Direct_address (ip,port) -> + ((Ip.to_string ip) ^ ":" ^ string_of_int port) + | Indirect_address _ | Invalid_address _ -> "Indirect" + ) + + with _ -> + + try + match c.client_kind with + Direct_address (ip,port) -> + ((Ip.to_string ip) ^ ":" ^ string_of_int port) + | Indirect_address _ | Invalid_address _ -> "Indirect" + with _ -> "" + ) + in + log_chat_message cip (client_num c) c.client_name ("data:image/bmp;base64," ^ b64data) + + + | M.EmuleCaptchaRes t -> + let cip = + ( + try + + match c.client_source.DonkeySources.source_sock with + Connection sock -> + (Ip.to_string (peer_ip sock) ^ ":" ^ string_of_int (peer_port sock)) + | _ -> (match c.client_kind with + Direct_address (ip,port) -> + ((Ip.to_string ip) ^ ":" ^ string_of_int port) + | Indirect_address _ | Invalid_address _ -> "Indirect" + ) + + with _ -> + + try + match c.client_kind with + Direct_address (ip,port) -> + ((Ip.to_string ip) ^ ":" ^ string_of_int port) + | Indirect_address _ | Invalid_address _ -> "Indirect" + with _ -> "" + ) + in + log_chat_message cip (client_num c) c.client_name ( + if t = 0 then + "You have correctly solved the captcha and your message was sent." + else if t = 1 then + "Wrong answer to the captcha, so your message was not sent. You will only be sent 3 captchas. Try sending another message to receive another captcha challenge." + else if t = 2 then + "3 captchas have already been sent to you. Fail." + else + "Unknown captcha state!?" + ) + | M.QueryChunkMd4Req t when !CommonGlobals.has_upload = 0 -> diff --git a/src/networks/donkey/donkeyProtoClient.ml b/src/networks/donkey/donkeyProtoClient.ml index c63c6a32..c7162014 100644 --- a/src/networks/donkey/donkeyProtoClient.ml +++ b/src/networks/donkey/donkeyProtoClient.ml @@ -69,6 +69,7 @@ let mldonkey_emule_proto = emule_extmultipacket = 0; emule_largefiles = 1; emule_kad_version = 0; + emule_support_captcha = 1; } let emule_miscoptions1 m = @@ -121,18 +122,20 @@ let print_emule_proto_miscoptions1 m = let emule_miscoptions2 m = let o = + (m.emule_support_captcha lsl 11) lor (m.emule_largefiles lsl 4) in Int64.of_int o let update_emule_proto_from_miscoptions2 m o = let o = Int64.to_int o in - m.emule_require_crypt <- (o lsr 9) land 0x1; - m.emule_request_crypt <- (o lsr 8) land 0x1; - m.emule_support_crypt <- (o lsr 7) land 0x1; - m.emule_extmultipacket <- (o lsr 5) land 0x1; - m.emule_largefiles <- (o lsr 4) land 0x1; - m.emule_kad_version <- (o lsr 0) land 0xf + m.emule_support_captcha <- (o lsr 11) land 0x1; + m.emule_require_crypt <- (o lsr 9) land 0x1; + m.emule_request_crypt <- (o lsr 8) land 0x1; + m.emule_support_crypt <- (o lsr 7) land 0x1; + m.emule_extmultipacket <- (o lsr 5) land 0x1; + m.emule_largefiles <- (o lsr 4) land 0x1; + m.emule_kad_version <- (o lsr 0) land 0xf let print_emule_proto_miscoptions2 m = let buf = Buffer.create 50 in @@ -142,6 +145,7 @@ let print_emule_proto_miscoptions2 m = if m.emule_extmultipacket <> 0 then Printf.bprintf buf " extmultipacket %d\n" m.emule_extmultipacket; if m.emule_largefiles <> 0 then Printf.bprintf buf " largefiles %d\n" m.emule_largefiles; if m.emule_kad_version <> 0 then Printf.bprintf buf " kad_version %d\n" m.emule_kad_version; + if m.emule_support_captcha <> 0 then Printf.bprintf buf " support_captcha %d\n" m.emule_support_captcha; Buffer.contents buf let emule_compatoptions m = @@ -941,6 +945,39 @@ module EmulePublicKeyReq = struct end + +module EmuleCaptchaReq = struct + + type t = string + + let print t = + lprintf_nl "EmuleCaptchaReq [CAPTCHA BMP length=%d bytedata=%s]" (String.length t) (String.escaped t) + + let parse len s = + String.sub s 2 (len - 2) + + let write buf t = + buf_estring buf t + + end + + +module EmuleCaptchaRes = struct + + type t = int + + let print t = + lprintf_nl "EmuleCaptchaRes RESPONSE=%d" t + + let parse s = + get_uint8 s 1 + + let write buf t = + buf_int8 buf t + + end + + module EmuleSecIdentStateReq = struct type t = { @@ -1105,12 +1142,12 @@ module EmuleCompressedPart = struct usesixtyfour = usesixtyfour; statpos = if usesixtyfour then get_int64 s 17 else get_uint64_32 s 17; newsize = if usesixtyfour then get_uint64_32 s 25 else get_uint64_32 s 21; - bloc = if usesixtyfour then String.sub s 29 (len-29) else String.sub s 25 (len-25) + bloc = if usesixtyfour then String.sub s 29 (len-29) else String.sub s 25 (len-25) } let print t = lprintf_nl "EmuleCompressedPart for %s %Ld %Ld len %d" - (Md4.to_string t.md4) t.statpos t.newsize (String.length t.bloc) + (Md4.to_string t.md4) t.statpos t.newsize (String.length t.bloc) let write buf t = buf_md4 buf t.md4; @@ -1177,6 +1214,8 @@ type t = | EmuleMultiPacketAnswerReq of Md4.t * t list | EmuleCompressedPart of EmuleCompressedPart.t | EmulePortTestReq of EmulePortTestReq.t +| EmuleCaptchaReq of EmuleCaptchaReq.t +| EmuleCaptchaRes of EmuleCaptchaRes.t let rec print t = begin @@ -1248,6 +1287,10 @@ let rec print t = EmuleCompressedPart.print t | EmulePortTestReq t -> EmulePortTestReq.print t + | EmuleCaptchaReq t -> + EmuleCaptchaReq.print t + | EmuleCaptchaRes t -> + EmuleCaptchaRes.print t | UnknownReq (opcode, s) -> let len = String.length s in lprintf_nl "UnknownReq: magic (%d), opcode (%d) len (%d)" opcode @@ -1379,8 +1422,9 @@ let rec parse_emule_packet emule opcode len s = EmuleCompressedPart (EmuleCompressedPart.parse true len s) | 0xa2 -> BlocReq (Bloc.parse true len s) (* OP_SENDINGPART_I64 *) | 0xa3 -> QueryBlocReq (QueryBloc.parse true len s) (*OP_REQUESTPARTS_I64 *) - | 0xfe (* 254 *) -> - EmulePortTestReq s + | 0xa5 (* 165 *) -> EmuleCaptchaReq (EmuleCaptchaReq.parse len s) (* OP_CHATCAPTCHAREQ *) + | 0xa6 (* 166 *) -> EmuleCaptchaRes (EmuleCaptchaRes.parse s) (* OP_CHATCAPTCHARES *) + | 0xfe (* 254 *) -> EmulePortTestReq s | code -> if !CommonOptions.verbose_unknown_messages then @@ -1495,6 +1539,8 @@ let write emule buf t = | EmuleClientInfoReq _ | EmuleFileDescReq _ | EmuleQueueRankingReq _ + | EmuleCaptchaReq _ + | EmuleCaptchaRes _ | EmuleCompressedPart _ -> 0xC5 | QueryBlocReq t when t.QueryBloc.usesixtyfour -> 0xC5 @@ -1664,7 +1710,15 @@ let write emule buf t = | EmulePortTestReq t -> buf_int8 buf 0xfe; - EmulePortTestReq.write buf; + EmulePortTestReq.write buf + + | EmuleCaptchaReq t -> + buf_int8 buf 0xa5; + EmuleCaptchaReq.write buf t + + | EmuleCaptchaRes t -> + buf_int8 buf 0xa6; + EmuleCaptchaRes.write buf t | UnknownReq (opcode, s) -> Buffer.add_string buf s diff --git a/src/networks/donkey/donkeyTypes.ml b/src/networks/donkey/donkeyTypes.ml index 917488c8..c26bf9b4 100644 --- a/src/networks/donkey/donkeyTypes.ml +++ b/src/networks/donkey/donkeyTypes.ml @@ -63,6 +63,7 @@ type emule_proto = { mutable emule_extmultipacket : int; mutable emule_largefiles : int; mutable emule_kad_version : int; + mutable emule_support_captcha : int; } type emule_tag_name = @@ -730,6 +731,7 @@ let dummy_emule_proto = { emule_extmultipacket = 0; emule_largefiles = 0; emule_kad_version = 0; + emule_support_captcha = 0; } let emule_proto () = -- 2.11.4.GIT