1267 lines
32 KiB
Diff
1267 lines
32 KiB
Diff
---
|
|
programs/network/ircc/ircc.asm | 76 ++-
|
|
programs/network/ircc/ircc.ini | 6 +-
|
|
programs/network/ircc/serverparser.inc | 107 +++-
|
|
programs/network/ircc/userparser.inc | 797 +++++++++++++++++++++++--
|
|
4 files changed, 912 insertions(+), 74 deletions(-)
|
|
|
|
diff --git a/programs/network/ircc/ircc.asm b/programs/network/ircc/ircc.asm
|
|
index 32a26d9e6..2ea8325a8 100644
|
|
--- a/programs/network/ircc/ircc.asm
|
|
+++ b/programs/network/ircc/ircc.asm
|
|
@@ -13,7 +13,7 @@
|
|
;; ;;
|
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
|
|
-version equ '0.36b'
|
|
+version equ '0.36b.vcrpt'
|
|
|
|
; connection status
|
|
STATUS_DISCONNECTED = 0
|
|
@@ -69,12 +69,16 @@ MAX_CHANNEL_LEN = 40
|
|
MAX_CHANNELS = 37
|
|
|
|
MAX_COMMAND_LEN = 512
|
|
+MAX_COMMAND_LEN_BYTES = MAX_COMMAND_LEN*4
|
|
|
|
PACKETBUF_SIZE = 1024
|
|
PATH_SIZE = 1024
|
|
PARAM_SIZE = 1024
|
|
SERVERCOMMAND_SIZE = 600
|
|
|
|
+CRPT_KEY_LEN = 64
|
|
+crpt_key_len_print equ '64'
|
|
+
|
|
TIMESTAMP = 3 ; 3 = hh:mm:ss, 2 = hh:mm, 0 = no timestamp
|
|
|
|
MAX_WINDOWNAME_LEN = 256
|
|
@@ -104,12 +108,33 @@ use32
|
|
dd param
|
|
dd path
|
|
|
|
-include "../../macros.inc"
|
|
-include "../../proc32.inc"
|
|
-include "../../dll.inc"
|
|
-include "../../network.inc"
|
|
-include "../../struct.inc"
|
|
-include "../../develop/libraries/box_lib/trunk/box_lib.mac"
|
|
+; include "../../macros.inc"
|
|
+; include "../../proc32.inc"
|
|
+; include "../../dll.inc"
|
|
+; include "../../network.inc"
|
|
+; include "../../struct.inc"
|
|
+; include "../../develop/libraries/box_lib/trunk/box_lib.mac"
|
|
+include "./external/macros.inc"
|
|
+include "./external/proc32.inc"
|
|
+include "./external/dll.inc"
|
|
+include "./external/network.inc"
|
|
+include "./external/struct.inc"
|
|
+include "./external/box_lib.mac"
|
|
+
|
|
+include "./TLS-Library-RNG/hmac.inc"
|
|
+include "./TLS-Library-RNG/PRF.inc"
|
|
+include "./TLS-Library-RNG/SHA256.INC"
|
|
+include "./TLS-Library-RNG/entropy.inc"
|
|
+
|
|
+RANDOM_BUFFER_SIZE = b + 3 * l ; 'b' and 'l' are defined at hmac.inc
|
|
+ ; currently, b = 32 and l = 12, so:
|
|
+ ; RANDOM_BUFFER_SIZE = (b + 3 * l) = (32 + 3 * 12) = 68
|
|
+ ; ^ should be equal or larger than (CRPT_KEY_LEN+1) = 64+1 = 65
|
|
+RANDOM_BUFFER_SIZE_TO_CONVERT = CRPT_KEY_LEN+1 ; from 68 random_bytes, convert only 65 to ASCII
|
|
+random_buffer db RANDOM_BUFFER_SIZE dup(0)
|
|
+
|
|
+ENTROPY_SIZE = 56
|
|
+entropy db ENTROPY_SIZE dup(255), 0
|
|
|
|
struct window
|
|
data_ptr dd ?
|
|
@@ -346,6 +371,9 @@ exit:
|
|
; Close all open windows
|
|
call window_close_all
|
|
|
|
+; Erase RAM areas which could contain the crpt stuff
|
|
+ call clear_crpt_stuff
|
|
+
|
|
; Erase RAM areas which could contain the connection details
|
|
xor eax, eax
|
|
mov edi, irc_server_name
|
|
@@ -468,6 +496,9 @@ action_header db 3, '6* ', 0
|
|
ctcp_header db 3, '13-> [', 0
|
|
ctcp_header_recv db 3, '13', 0
|
|
msg_header db 3, '7-> *', 0
|
|
+msg_header_recv db 3, '2', 0
|
|
+msg_header_recv_priv db 3, '12', 0
|
|
+msg_is_private db 0
|
|
ctcp_version db '] VERSION', 10, 0
|
|
ctcp_ping db '] PING', 10, 0
|
|
ctcp_time db '] TIME', 10, 0
|
|
@@ -487,6 +518,21 @@ str_topic db 'Topic is "', 0
|
|
str_topic_end db '"', 10, 0
|
|
str_setby db 'Set by ', 0
|
|
|
|
+str_crptstate db 10, 3, '4* Encrption is now ', 0
|
|
+str_expdstate db 10, 3, '4* Expansion is now ', 0
|
|
+str_shftstate db 10, 3, '4* Shifting is now ', 0
|
|
+str_enabled db 3, '12ENABLED', 10, 0
|
|
+str_disabled db 3, '7DISABLED', 10, 0
|
|
+str_crptnote db 3, '3NOTE:', 3, '7 its the enhanced Vigenere! Currently it', 10
|
|
+ db 3, '7supports 7-bit ASCII symbols: 32-126 code range', 10
|
|
+ db 3, '5Other, e.g. 2-byte RUS char, will not be crpted', 10
|
|
+ db 3, '7Also, your messages will be expanded + shifted', 10
|
|
+ db 3, '7to slightly improve the encrption strength. Its', 10
|
|
+ db 3, '7possible to enable/disable with /expd and /shft', 10, 0
|
|
+str_printkey db ', key = ', 0
|
|
+str_keylenerror db 'ERROR: length of your key is not ', crpt_key_len_print, ' (CRPT_KEY_LEN)', 10, 0
|
|
+str_not7bitasciirange db 'ERROR: some of your chars arent from 7-bit ASCII 32-126 code range', 10, 0
|
|
+
|
|
str_connecting db 3, '3* Connecting to ', 0
|
|
str_sockerr db 3, '5* Socket error', 10, 0
|
|
str_dnserr db 3, '5* Unable to resolve hostname', 10, 0
|
|
@@ -509,6 +555,7 @@ str_help db 'The following commands are available:', 10
|
|
db '/real <real name> : change real name', 10
|
|
db '/server <address> : connect to server', 10
|
|
db '/code <code> : change codepage (cp866, cp1251, or utf8)', 10
|
|
+ db '/crpt [', crpt_key_len_print, '-byte key] : enable/disable the encrption (enhanced Vigenere)', 10
|
|
db '/join <channel> : join a channel', 10
|
|
db '/part <channel> : part from a channel', 10
|
|
db '/quit : quit server', 10
|
|
@@ -536,9 +583,14 @@ str_real db 'realname', 0
|
|
str_email db 'email', 0
|
|
str_quitmsg db 'quitmsg', 0
|
|
|
|
-default_nick db 'kolibri_user', 0
|
|
-default_real db 'Kolibri User', 0
|
|
-default_quit db 'KolibriOS forever', 0
|
|
+default_nick db 'anonymous', 0
|
|
+default_real db 'anonymous', 0
|
|
+default_quit db 'Leaving', 0
|
|
+
|
|
+crpt_state db 0 ; 0 - encrption is disabled, 1 - encrption is enabled
|
|
+crpt_key db CRPT_KEY_LEN+1 dup(0) ; +1 is for storing the null character
|
|
+expd_state db 0 ; 0 - expansion is disabled, 1 - expansion is enabled
|
|
+shft_state db 0 ; 0 - shifting is disabled, 1 - shifting is enabled
|
|
|
|
closing_cross db 'x',0
|
|
|
|
@@ -608,9 +660,11 @@ input_text db '/server irc.libera.chat', 0
|
|
|
|
I_END:
|
|
|
|
-user_command rb MAX_COMMAND_LEN*4
|
|
+user_command rb MAX_COMMAND_LEN_BYTES
|
|
.size dd ?
|
|
|
|
+msg_temp_buf rb MAX_COMMAND_LEN_BYTES ; currently used for shifting a message
|
|
+
|
|
utf8_bytes_rest dd ? ; bytes rest in current UTF8 sequence
|
|
utf8_char dd ? ; first bits of current UTF8 character
|
|
|
|
diff --git a/programs/network/ircc/ircc.ini b/programs/network/ircc/ircc.ini
|
|
index 3f082f148..3cac154d3 100644
|
|
--- a/programs/network/ircc/ircc.ini
|
|
+++ b/programs/network/ircc/ircc.ini
|
|
@@ -1,7 +1,7 @@
|
|
[user]
|
|
-nick = kolibri_user
|
|
-realname = tetten
|
|
-partmsg = KolibriOS forever
|
|
+nick = anonymous
|
|
+realname = anonymous
|
|
+partmsg = Leaving
|
|
|
|
[colors]
|
|
action1 = 0x000000aa
|
|
diff --git a/programs/network/ircc/serverparser.inc b/programs/network/ircc/serverparser.inc
|
|
index 587b8bfec..23610fef4 100644
|
|
--- a/programs/network/ircc/serverparser.inc
|
|
+++ b/programs/network/ircc/serverparser.inc
|
|
@@ -259,6 +259,7 @@ cmd_privmsg:
|
|
jne .channel
|
|
|
|
; private chat message
|
|
+ mov byte[msg_is_private], 1
|
|
push esi
|
|
mov esi, servercommand+1
|
|
call window_open
|
|
@@ -269,6 +270,7 @@ cmd_privmsg:
|
|
jmp .print
|
|
|
|
.channel:
|
|
+ mov byte[msg_is_private], 0
|
|
call window_open
|
|
test ebx, ebx
|
|
jz .fail
|
|
@@ -282,6 +284,20 @@ cmd_privmsg:
|
|
end if
|
|
|
|
push esi
|
|
+
|
|
+ ; different colors for the private and channel messages
|
|
+
|
|
+ mov esi, msg_header_recv_priv
|
|
+
|
|
+ cmp byte[msg_is_private], 1
|
|
+ je .is_private
|
|
+
|
|
+ mov esi, msg_header_recv
|
|
+
|
|
+ .is_private:
|
|
+
|
|
+ call print_asciiz
|
|
+
|
|
mov al, '<'
|
|
call print_char
|
|
|
|
@@ -296,6 +312,17 @@ cmd_privmsg:
|
|
call print_char
|
|
|
|
pop esi
|
|
+
|
|
+; decrpt user message, if selected
|
|
+
|
|
+ cmp byte[crpt_state], 0
|
|
+ je .dont_dcrpt_a_msg
|
|
+
|
|
+ ; pointer is already at esi
|
|
+ call dcrpt_a_msg
|
|
+
|
|
+ .dont_dcrpt_a_msg:
|
|
+
|
|
call print_asciiz
|
|
|
|
mov al, 10
|
|
@@ -309,6 +336,56 @@ cmd_privmsg:
|
|
ret
|
|
|
|
|
|
+; dcrpt_a_msg:
|
|
+; dcrpt a message, pointer to which is at ESI
|
|
+;
|
|
+; IN: ESI = ptr to encrpted message
|
|
+; OUT: ESI = ptr to dcrpted message
|
|
+
|
|
+dcrpt_a_msg:
|
|
+
|
|
+ push esi ebx eax
|
|
+
|
|
+ xor eax, eax
|
|
+
|
|
+ .cycle_dcrpt_a_msg:
|
|
+
|
|
+ cmp byte[esi], 0 ; if its the end of input, quit a cycle
|
|
+ je .exit_cycle_dcrpt_a_msg
|
|
+ cmp byte[esi], 1 ; if its the end of input, quit a cycle
|
|
+ je .exit_cycle_dcrpt_a_msg
|
|
+
|
|
+ cmp byte[esi], 0x7e ; check if a symbol is above 32-126 code range
|
|
+ ja .dcrpt_go_to_next_char
|
|
+ cmp byte[esi], 0x20 ; check if a symbol is below 32-126 code range
|
|
+ jb .dcrpt_go_to_next_char
|
|
+
|
|
+ mov bl, byte[crpt_key + eax]
|
|
+ cmp byte[esi], bl
|
|
+ jg .no_overflow
|
|
+
|
|
+ add byte[esi], 126
|
|
+ sub byte[esi], 31
|
|
+
|
|
+ .no_overflow:
|
|
+
|
|
+ sub byte[esi], bl
|
|
+ add byte[esi], 31
|
|
+
|
|
+ inc eax
|
|
+
|
|
+ .dcrpt_go_to_next_char:
|
|
+
|
|
+ inc esi
|
|
+
|
|
+ cmp eax, CRPT_KEY_LEN
|
|
+ jne .cycle_dcrpt_a_msg
|
|
+
|
|
+ .exit_cycle_dcrpt_a_msg:
|
|
+
|
|
+ pop eax ebx esi
|
|
+
|
|
+ ret
|
|
|
|
|
|
cmd_ctcp:
|
|
@@ -317,14 +394,18 @@ cmd_ctcp:
|
|
mov eax, dword[esi]
|
|
or eax, 0x20202020
|
|
|
|
+ cmp eax, 'acti'
|
|
+ je .action
|
|
+
|
|
+ cmp byte[crpt_state], 1 ; while the encrption is enabled
|
|
+ je .just_print ; do not process the ctcp requests
|
|
+
|
|
cmp eax, 'vers'
|
|
je .version
|
|
cmp eax, 'time'
|
|
je .time
|
|
cmp eax, 'ping'
|
|
je .ping
|
|
- cmp eax, 'acti'
|
|
- je .action
|
|
cmp eax, 'dcc ' ; TODO
|
|
je cmd_dcc
|
|
|
|
@@ -334,6 +415,16 @@ cmd_ctcp:
|
|
|
|
push esi
|
|
|
|
+; decrpt user message, if selected
|
|
+
|
|
+ cmp byte[crpt_state], 0
|
|
+ je .dont_dcrpt_a_msg_1
|
|
+
|
|
+ ; pointer is already at esi
|
|
+ call dcrpt_a_msg
|
|
+
|
|
+ .dont_dcrpt_a_msg_1:
|
|
+
|
|
if TIMESTAMP
|
|
call print_timestamp
|
|
end if
|
|
@@ -449,9 +540,19 @@ cmd_ctcp:
|
|
ret
|
|
|
|
.action:
|
|
- add esi, 7
|
|
+ add esi, 7 ; skip "ACTION "
|
|
push esi
|
|
|
|
+; decrpt user message, if selected
|
|
+
|
|
+ cmp byte[crpt_state], 0
|
|
+ je .dont_dcrpt_a_msg_2
|
|
+
|
|
+ ; pointer is already at esi
|
|
+ call dcrpt_a_msg
|
|
+
|
|
+ .dont_dcrpt_a_msg_2:
|
|
+
|
|
if TIMESTAMP
|
|
call print_timestamp
|
|
end if
|
|
diff --git a/programs/network/ircc/userparser.inc b/programs/network/ircc/userparser.inc
|
|
index 999513346..cea61c45d 100644
|
|
--- a/programs/network/ircc/userparser.inc
|
|
+++ b/programs/network/ircc/userparser.inc
|
|
@@ -23,7 +23,16 @@ user_parser:
|
|
mov esi, input_text
|
|
mov edi, user_command
|
|
call recode ; Convert to UTF-8
|
|
- mov byte[edi], 0x0 ; Terminate string with \0
|
|
+
|
|
+ cmp byte[user_command], '/' ; is it a server command ?
|
|
+ je .dont_change_my_msg
|
|
+
|
|
+ mov esi, user_command
|
|
+ call change_my_msg ; expand/shift user message, if selected
|
|
+
|
|
+ .dont_change_my_msg:
|
|
+
|
|
+ mov dword[edi], 0x00000a0d ; terminate the line
|
|
sub edi, user_command
|
|
mov [user_command.size], edi
|
|
|
|
@@ -62,6 +71,18 @@ user_parser:
|
|
mov al, 10
|
|
call print_char
|
|
|
|
+; encrpt user message, if selected
|
|
+
|
|
+ cmp byte[crpt_state], 0
|
|
+ je .dont_crpt_my_msg
|
|
+
|
|
+ push esi
|
|
+ mov esi, user_command
|
|
+ call crpt_my_msg
|
|
+ pop esi
|
|
+
|
|
+ .dont_crpt_my_msg:
|
|
+
|
|
; and now send it to the server
|
|
mov dword[packetbuf], 'PRIV'
|
|
mov dword[packetbuf+4], 'MSG '
|
|
@@ -150,6 +171,9 @@ user_commands:
|
|
dd 'serv', cmd_usr_server
|
|
dd 'help', cmd_usr_help
|
|
dd 'code', cmd_usr_code
|
|
+ dd 'crpt', cmd_usr_crpt
|
|
+ dd 'expd', cmd_usr_expd
|
|
+ dd 'shft', cmd_usr_shft
|
|
|
|
.number2 = ($ - user_commands) / 8
|
|
|
|
@@ -172,6 +196,12 @@ cmd_usr_msg:
|
|
mov dword[packetbuf+4], 'MSG '
|
|
lea edi, [packetbuf+8]
|
|
|
|
+ ; in addition, need to find (nickname_length + 1) and put it to ECX register
|
|
+
|
|
+ push ecx ebx
|
|
+ xor ebx, ebx
|
|
+ xor ecx, ecx
|
|
+
|
|
@@:
|
|
lodsb
|
|
test al, al
|
|
@@ -180,6 +210,7 @@ cmd_usr_msg:
|
|
je .fail
|
|
cmp al, 13
|
|
je .fail
|
|
+ inc ecx
|
|
stosb
|
|
cmp al, ' '
|
|
jne @r
|
|
@@ -187,24 +218,26 @@ cmd_usr_msg:
|
|
mov al, ':'
|
|
stosb
|
|
|
|
+; expand/shift user message, if selected
|
|
+
|
|
+ mov ebx, [user_command.size] ; total_length
|
|
+ sub ebx, ecx ; total_length - (nickname_length + 1)
|
|
+ sub ebx, 5 ; ^ - ("/msg " length) = real_message_length
|
|
+
|
|
push edi
|
|
- @@:
|
|
- lodsb
|
|
- test al, al
|
|
- jz @f
|
|
- cmp al, 10
|
|
- je @f
|
|
- cmp al, 13
|
|
- je @f
|
|
- stosb
|
|
- jmp @r
|
|
- @@:
|
|
-; end the command with a CRLF
|
|
- mov ax, 0x0a0d
|
|
- stosw
|
|
- mov byte[edi], 0
|
|
|
|
-; now print to the window
|
|
+ mov edi, esi
|
|
+ add edi, ebx
|
|
+
|
|
+ call change_my_msg ; expand/shift user message, if selected
|
|
+
|
|
+ mov dword[edi], 0x00000a0d ; terminate the line
|
|
+
|
|
+ pop edi ebx ecx
|
|
+
|
|
+ push esi esi
|
|
+
|
|
+; print to local window
|
|
if TIMESTAMP
|
|
call print_timestamp
|
|
end if
|
|
@@ -224,6 +257,35 @@ cmd_usr_msg:
|
|
|
|
pop esi
|
|
call print_asciiz
|
|
+ pop esi
|
|
+
|
|
+; encrpt user message, if selected
|
|
+
|
|
+ cmp byte[crpt_state], 0
|
|
+ je .dont_crpt_my_msg
|
|
+
|
|
+ ; pointer is already at esi
|
|
+ call crpt_my_msg
|
|
+
|
|
+ .dont_crpt_my_msg:
|
|
+
|
|
+; copy the message itself
|
|
+ @@:
|
|
+ lodsb
|
|
+ test al, al
|
|
+ jz @f
|
|
+ cmp al, 10
|
|
+ je @f
|
|
+ cmp al, 13
|
|
+ je @f
|
|
+ stosb
|
|
+ jmp @r
|
|
+ @@:
|
|
+; end the command with a CRLF
|
|
+ mov ax, 0x0a0d
|
|
+ stosw
|
|
+
|
|
+; now send it to the server
|
|
|
|
lea esi, [edi - packetbuf]
|
|
mcall send, [socketnum], packetbuf, , 0
|
|
@@ -439,6 +501,561 @@ cmd_usr_code:
|
|
ret
|
|
|
|
|
|
+; User wants to enable or disable the encrption
|
|
+
|
|
+cmd_usr_crpt:
|
|
+
|
|
+ push esi ecx eax
|
|
+
|
|
+ mov esi, str_crptstate
|
|
+ call print_asciiz
|
|
+
|
|
+ cmp byte [crpt_state], 0
|
|
+ je .crpt_enable ; if disabled, lets see if we could enable
|
|
+ ; else, if enabled - we are going to disable
|
|
+
|
|
+ call clear_crpt_stuff ; erase RAM areas which could contain the crpt stuff
|
|
+
|
|
+ mov byte [crpt_state], 0
|
|
+ mov byte [expd_state], 0
|
|
+ mov byte [shft_state], 0
|
|
+
|
|
+ mov esi, str_disabled
|
|
+ call print_asciiz
|
|
+
|
|
+ mov [edit1.max], USERCMD_MAX_SIZE ; max size of input textbox
|
|
+
|
|
+ jmp .usr_crpt_done
|
|
+
|
|
+ .crpt_enable:
|
|
+
|
|
+ ; check if the user-specified encrption key is meeting the requirements
|
|
+
|
|
+ call crpt_check_key
|
|
+ cmp ecx, 0
|
|
+ jne .usr_crpt_done ; if not 0 there is a problem with key, dont enable
|
|
+
|
|
+ ; enable the encrption and print a couple of messages
|
|
+
|
|
+ mov byte [crpt_state], 1
|
|
+ mov byte [expd_state], 1
|
|
+ mov byte [shft_state], 1
|
|
+
|
|
+ mov esi, str_enabled
|
|
+ call print_asciiz
|
|
+
|
|
+ mov esi, str_crptnote
|
|
+ call print_asciiz
|
|
+
|
|
+ ; copy the encrption key from the user_command (skipping "/crpt ") to its storage
|
|
+
|
|
+ mov ecx, CRPT_KEY_LEN
|
|
+ mov esi, user_command+6
|
|
+ mov edi, crpt_key
|
|
+ @@:
|
|
+ lodsb
|
|
+ cmp al, 13
|
|
+ je @f
|
|
+ stosb
|
|
+ dec ecx
|
|
+ jnz @r
|
|
+ @@:
|
|
+ xor al, al
|
|
+ stosb
|
|
+
|
|
+ mov edi, user_command
|
|
+ mov ebx, MAX_COMMAND_LEN_BYTES
|
|
+ call clearmem
|
|
+
|
|
+ mov [edit1.max], CRPT_KEY_LEN ; max size of input textbox
|
|
+
|
|
+ .usr_crpt_done:
|
|
+
|
|
+ mov al, 10
|
|
+ call print_char
|
|
+
|
|
+ pop eax ecx esi
|
|
+
|
|
+ ret
|
|
+
|
|
+; crpt_check_key:
|
|
+; check if the user-specified encrption key is meeting the requirements
|
|
+;
|
|
+; IN: ECX = ptr to user_command with encrption key
|
|
+; OUT: ECX = 0 if valid,
|
|
+; = 1 if any symbols do not belong to 32-126 code range,
|
|
+; >= 6 (keylen + 6) if a key is too short or too long
|
|
+
|
|
+crpt_check_key:
|
|
+
|
|
+ mov ecx, 6 ; skip "/crpt "
|
|
+
|
|
+ .crpt_find_keylen_cycle:
|
|
+
|
|
+ mov al, byte[user_command + ecx]
|
|
+
|
|
+ cmp al, 0x00 ; if its the end of input, quit a cycle
|
|
+ je .crpt_findkeylen_done
|
|
+ cmp al, 0x0a ; if its the end of input, quit a cycle
|
|
+ je .crpt_findkeylen_done
|
|
+ cmp al, 0x0d ; if its the end of input, quit a cycle
|
|
+ je .crpt_findkeylen_done
|
|
+
|
|
+ cmp al, 0x7e ; check if a symbol is above 32-126 code range
|
|
+ ja .crpt_not7bitasciirange
|
|
+ cmp al, 0x20 ; check if a symbol is below 32-126 code range
|
|
+ jb .crpt_not7bitasciirange
|
|
+
|
|
+ inc ecx
|
|
+ jmp .crpt_find_keylen_cycle
|
|
+
|
|
+ .crpt_not7bitasciirange:
|
|
+
|
|
+ mov esi, str_not7bitasciirange
|
|
+ call print_asciiz
|
|
+
|
|
+ mov ecx, 1
|
|
+ ret ; error code = 1
|
|
+
|
|
+ .crpt_findkeylen_done:
|
|
+
|
|
+ cmp ecx, CRPT_KEY_LEN+6 ; +6 because of "/crpt "
|
|
+ je .check_key_done
|
|
+
|
|
+ mov esi, str_keylenerror
|
|
+ call print_asciiz
|
|
+
|
|
+ ret ; error code = keylen + 6
|
|
+
|
|
+ .check_key_done:
|
|
+
|
|
+ mov ecx, 0 ; no error
|
|
+
|
|
+ ret
|
|
+
|
|
+; crpt_my_msg:
|
|
+; encrpt my message, pointer to which is at ESI
|
|
+;
|
|
+; IN: ESI = ptr to source message
|
|
+; OUT: ESI = ptr to encrpted message
|
|
+
|
|
+crpt_my_msg:
|
|
+
|
|
+ push esi ebx eax
|
|
+
|
|
+ xor eax, eax
|
|
+
|
|
+ .cycle_crpt_my_msg:
|
|
+
|
|
+ cmp byte[esi], 0x00
|
|
+ je .exit_cycle_crpt_my_msg
|
|
+ cmp byte[esi], 0x01
|
|
+ je .exit_cycle_crpt_my_msg
|
|
+ cmp byte[esi], 0x0a
|
|
+ je .exit_cycle_crpt_my_msg
|
|
+ cmp byte[esi], 0x0d
|
|
+ je .exit_cycle_crpt_my_msg
|
|
+
|
|
+ cmp byte[esi], 0x7e ; check if a symbol is above 32-126 code range
|
|
+ ja .crpt_go_to_next_char
|
|
+ cmp byte[esi], 0x20 ; check if a symbol is below 32-126 code range
|
|
+ jb .crpt_go_to_next_char
|
|
+
|
|
+ mov bl, byte[crpt_key + eax]
|
|
+ sub bl, 31
|
|
+ add byte[esi], bl
|
|
+ cmp byte[esi], 127
|
|
+ jb .no_overflow
|
|
+
|
|
+ sub byte[esi], 126
|
|
+ add byte[esi], 31
|
|
+
|
|
+ .no_overflow:
|
|
+
|
|
+ inc eax
|
|
+
|
|
+ .crpt_go_to_next_char:
|
|
+
|
|
+ inc esi
|
|
+
|
|
+ cmp eax, CRPT_KEY_LEN
|
|
+ jne .cycle_crpt_my_msg
|
|
+
|
|
+ .exit_cycle_crpt_my_msg:
|
|
+
|
|
+ pop eax ebx esi
|
|
+
|
|
+ ret
|
|
+
|
|
+; change_my_msg:
|
|
+; expand/shift user message, if selected
|
|
+;
|
|
+; IN: ESI = ptr to the beginning of source message
|
|
+; EDI = ptr to the end of source message
|
|
+
|
|
+change_my_msg:
|
|
+
|
|
+ push edx ecx
|
|
+
|
|
+ xor edx, edx
|
|
+ add dl, byte[expd_state]
|
|
+ add dl, byte[shft_state]
|
|
+
|
|
+ cmp edx, 0
|
|
+ je .dont_change_my_msg
|
|
+
|
|
+ ; put the length of a message into EDX register
|
|
+
|
|
+ mov edx, edi
|
|
+ sub edx, esi
|
|
+
|
|
+ ; EDX = length of a message (input argument for shift_my_msg if called)
|
|
+
|
|
+ call fill_random_buffer
|
|
+ mov ecx, RANDOM_BUFFER_SIZE_TO_CONVERT
|
|
+ call convert_random_buffer_to_ascii
|
|
+
|
|
+ cmp byte[expd_state], 0
|
|
+ je .dont_expand_my_msg
|
|
+
|
|
+ call expand_my_msg
|
|
+ mov edx, CRPT_KEY_LEN
|
|
+
|
|
+ .dont_expand_my_msg:
|
|
+
|
|
+ cmp byte[shft_state], 0
|
|
+ je .dont_shift_my_msg
|
|
+
|
|
+ call shift_my_msg
|
|
+
|
|
+ .dont_shift_my_msg:
|
|
+
|
|
+ .dont_change_my_msg:
|
|
+
|
|
+ pop ecx edx
|
|
+
|
|
+ ret
|
|
+
|
|
+
|
|
+; User wants to enable or disable the expansion
|
|
+cmd_usr_expd:
|
|
+ push esi
|
|
+ mov esi, str_expdstate
|
|
+ call print_asciiz
|
|
+ cmp byte[expd_state], 0
|
|
+ je .expd_enable
|
|
+ jmp .expd_disable
|
|
+ .expd_enable:
|
|
+ mov byte[expd_state], 1
|
|
+ mov esi, str_enabled
|
|
+ call print_asciiz
|
|
+ jmp .exit_expd
|
|
+ .expd_disable:
|
|
+ mov byte[expd_state], 0
|
|
+ mov esi, str_disabled
|
|
+ call print_asciiz
|
|
+ .exit_expd:
|
|
+ pop esi
|
|
+ ret
|
|
+
|
|
+; expand_my_msg:
|
|
+; expand my message, pointer to which is at ESI, with random bytes
|
|
+;
|
|
+; IN: ESI = ptr to the beginning of source message
|
|
+; EDI = ptr to the end of source message
|
|
+;
|
|
+; NOTE: this function depends on random, before calling this function it is required to:
|
|
+;
|
|
+; call fill_random_buffer
|
|
+; call convert_random_buffer_to_ascii
|
|
+
|
|
+expand_my_msg:
|
|
+
|
|
+ push esi edx ecx ebx eax
|
|
+
|
|
+ mov ebx, esi
|
|
+ add ebx, CRPT_KEY_LEN
|
|
+
|
|
+ cmp ebx, edi
|
|
+ jna .cant_expand
|
|
+
|
|
+ sub ebx, edi
|
|
+
|
|
+ xor eax, eax
|
|
+ xor ecx, ecx
|
|
+ mov edx, random_buffer
|
|
+
|
|
+ .cycle_expand_my_msg_with_random_buf:
|
|
+
|
|
+ mov al, byte[edx]
|
|
+ stosb
|
|
+
|
|
+ inc edx
|
|
+ inc ecx
|
|
+
|
|
+ cmp ecx, ebx
|
|
+ jne .cycle_expand_my_msg_with_random_buf
|
|
+
|
|
+ .cant_expand:
|
|
+
|
|
+ pop eax ebx ecx edx esi
|
|
+
|
|
+ ret
|
|
+
|
|
+; User wants to enable or disable the shifting
|
|
+cmd_usr_shft:
|
|
+ push esi
|
|
+ mov esi, str_shftstate
|
|
+ call print_asciiz
|
|
+ cmp byte[shft_state], 0
|
|
+ je .shft_enable
|
|
+ jmp .shft_disable
|
|
+ .shft_enable:
|
|
+ mov byte[shft_state], 1
|
|
+ mov esi, str_enabled
|
|
+ call print_asciiz
|
|
+ jmp .exit_shft
|
|
+ .shft_disable:
|
|
+ mov byte[shft_state], 0
|
|
+ mov esi, str_disabled
|
|
+ call print_asciiz
|
|
+ .exit_shft:
|
|
+ pop esi
|
|
+ ret
|
|
+
|
|
+; shift_my_msg:
|
|
+; shift my message, pointer to which is at ESI, "clockwise" (right shift) to a random offset
|
|
+;
|
|
+; IN/OUT: ESI = ptr to the beginning of source message
|
|
+; EDX = length of source message
|
|
+;
|
|
+; NOTE: this function depends on random, before calling this function it is required to:
|
|
+;
|
|
+; call fill_random_buffer
|
|
+; call convert_random_buffer_to_ascii
|
|
+
|
|
+shift_my_msg:
|
|
+
|
|
+ push edi esi ecx ebx eax
|
|
+
|
|
+ ; check if a length of source message is between the supported limits
|
|
+
|
|
+ cmp edx, 2
|
|
+ jb .exit_shift_my_msg
|
|
+ cmp edx, CRPT_KEY_LEN
|
|
+ ja .exit_shift_my_msg
|
|
+
|
|
+ ; get a value of random offset, and move it to EBX register
|
|
+
|
|
+ xor eax, eax
|
|
+
|
|
+ mov ebx, random_buffer
|
|
+ add ebx, edx
|
|
+ inc ebx
|
|
+
|
|
+ mov al, byte[ebx]
|
|
+
|
|
+ ; random offset should not be larger than a message length,
|
|
+ ; so if its larger: RANDOM OFFSET = RANDOM_VALUE mod MESSAGE_LENGTH
|
|
+
|
|
+ xor ebx, ebx
|
|
+
|
|
+ cmp eax, edx
|
|
+ jb .skip_division
|
|
+
|
|
+ div dl
|
|
+ mov al, ah
|
|
+
|
|
+ .skip_division:
|
|
+
|
|
+ mov bl, al
|
|
+
|
|
+ ; copy the right part of message (starting with EBX offset) to the temporary buffer
|
|
+
|
|
+ xor eax, eax
|
|
+
|
|
+ mov ecx, edx
|
|
+ sub ecx, ebx
|
|
+
|
|
+ mov edi, msg_temp_buf
|
|
+ add edi, ebx
|
|
+
|
|
+ call shift_my_msg_cycle
|
|
+
|
|
+ ; copy the left part of message (before the ebx offset) to the temporary buffer,
|
|
+ ; placing it after the right part which we have copied previously
|
|
+
|
|
+ mov edi, msg_temp_buf
|
|
+ mov ecx, edx
|
|
+
|
|
+ call shift_my_msg_cycle
|
|
+
|
|
+ ; copy the temporary buffer, which contains a "clockwise" right shifted message,
|
|
+ ; replacing the original message
|
|
+
|
|
+ mov edi, esi
|
|
+ sub edi, edx
|
|
+ mov esi, msg_temp_buf
|
|
+ mov ebx, edx
|
|
+
|
|
+ call copymem
|
|
+
|
|
+ ; check if the ending symbol of user_command is not a header for 2-byte char
|
|
+
|
|
+ dec edi
|
|
+
|
|
+ cmp byte[edi], 0xd7
|
|
+ ja .exit_shift_my_msg
|
|
+ cmp byte[edi], 0xd0
|
|
+ jb .exit_shift_my_msg
|
|
+
|
|
+ ; this 2-byte char will be splitted and corrupted by this shifting operation,
|
|
+ ; we could only replace it with a couple of random chars to avoid the problems
|
|
+
|
|
+ mov eax, random_buffer
|
|
+ add eax, edx
|
|
+
|
|
+ ; replace the header with random_buffer[message_length-1] unused random character
|
|
+
|
|
+ dec eax
|
|
+ mov bl, byte[eax]
|
|
+ mov byte[edi], bl
|
|
+
|
|
+ ; replace the letter with random_buffer[message_length ] unused random character
|
|
+
|
|
+ inc eax
|
|
+ mov bl, byte[eax]
|
|
+ sub edi, edx
|
|
+ inc edi
|
|
+ mov byte[edi], bl
|
|
+
|
|
+ .exit_shift_my_msg:
|
|
+
|
|
+ pop eax ebx ecx esi edi
|
|
+
|
|
+ ret
|
|
+
|
|
+; shift_my_msg_cycle:
|
|
+; helper cycle for a shift_my_msg function, copies the left or right part of the message
|
|
+;
|
|
+; IN/OUT: ESI = ptr to the source
|
|
+; EAX = current offset from the beginning of source
|
|
+; ECX = offset from the beginning of source, where to stop the copying
|
|
+; EDI = ptr to the destination
|
|
+
|
|
+shift_my_msg_cycle:
|
|
+
|
|
+ .cycle_shift_my_msg:
|
|
+
|
|
+ cmp eax, ecx
|
|
+ je .exit_cycle_shift_my_msg
|
|
+
|
|
+ mov bl, byte[esi]
|
|
+ mov byte[edi], bl
|
|
+
|
|
+ inc eax
|
|
+ inc esi
|
|
+ inc edi
|
|
+
|
|
+ jmp .cycle_shift_my_msg
|
|
+
|
|
+ .exit_cycle_shift_my_msg:
|
|
+
|
|
+ ret
|
|
+
|
|
+; copymem:
|
|
+; copy a memory area
|
|
+;
|
|
+; IN: ESI - ptr to source memory area
|
|
+; EDI - ptr to destination memory area
|
|
+; EBX - how many bytes to copy
|
|
+
|
|
+copymem:
|
|
+
|
|
+ push eax ecx
|
|
+
|
|
+ xor ecx, ecx
|
|
+
|
|
+ .cycle_copymem:
|
|
+
|
|
+ lodsb
|
|
+ stosb
|
|
+ inc ecx
|
|
+ cmp ecx, ebx
|
|
+ jb .cycle_copymem
|
|
+
|
|
+ pop ecx eax
|
|
+
|
|
+ ret
|
|
+
|
|
+; clearmem:
|
|
+; clear a memory area
|
|
+;
|
|
+; IN: EDI - pointer to a memory area
|
|
+; EBX - how many bytes to clear
|
|
+
|
|
+clearmem:
|
|
+
|
|
+ push eax ecx
|
|
+
|
|
+ xor al, al
|
|
+ xor ecx, ecx
|
|
+
|
|
+ .cycle_clearmem:
|
|
+
|
|
+ stosb
|
|
+ inc ecx
|
|
+ cmp ecx, ebx
|
|
+ jb .cycle_clearmem
|
|
+
|
|
+ pop ecx eax
|
|
+
|
|
+ ret
|
|
+
|
|
+; clear_crpt_stuff:
|
|
+; erase RAM areas which could contain the crpt stuff
|
|
+
|
|
+clear_crpt_stuff:
|
|
+
|
|
+ push edi ebx
|
|
+
|
|
+ mov edi, crpt_key
|
|
+ mov ebx, CRPT_KEY_LEN
|
|
+ call clearmem
|
|
+
|
|
+ mov edi, user_command
|
|
+ mov ebx, MAX_COMMAND_LEN_BYTES
|
|
+ call clearmem
|
|
+ mov edi, msg_temp_buf
|
|
+ call clearmem
|
|
+
|
|
+ mov edi, input_text
|
|
+ mov ebx, MAX_COMMAND_LEN
|
|
+ call clearmem
|
|
+
|
|
+ mov edi, packetbuf
|
|
+ mov ebx, PACKETBUF_SIZE
|
|
+ call clearmem
|
|
+
|
|
+ mov edi, path
|
|
+ mov ebx, PATH_SIZE
|
|
+ call clearmem
|
|
+
|
|
+ mov edi, param
|
|
+ mov ebx, PARAM_SIZE
|
|
+ call clearmem
|
|
+
|
|
+ mov edi, servercommand
|
|
+ mov ebx, SERVERCOMMAND_SIZE
|
|
+ call clearmem
|
|
+
|
|
+ mov edi, random_buffer
|
|
+ mov ebx, RANDOM_BUFFER_SIZE
|
|
+ call clearmem
|
|
+
|
|
+ pop ebx edi
|
|
+
|
|
+ ret
|
|
|
|
; User typed a part command
|
|
cmd_usr_part:
|
|
@@ -511,6 +1128,12 @@ cmd_usr_ctcp:
|
|
mov dword[packetbuf+4], 'MSG '
|
|
lea edi, [packetbuf+8]
|
|
|
|
+ ; in addition, need to find ("nickname/channel length" + 1) and put it to ECX register
|
|
+
|
|
+ push ecx ebx
|
|
+ xor ebx, ebx
|
|
+ xor ecx, ecx
|
|
+
|
|
; append the destination (nickname/channel)
|
|
@@:
|
|
lodsb
|
|
@@ -518,6 +1141,7 @@ cmd_usr_ctcp:
|
|
jz .fail
|
|
cmp al, ' '
|
|
je @f
|
|
+ inc ecx
|
|
stosb
|
|
jmp @r
|
|
@@:
|
|
@@ -527,28 +1151,28 @@ cmd_usr_ctcp:
|
|
mov al, 0x01
|
|
stosb
|
|
|
|
- push esi
|
|
+; expand/shift user message, if selected
|
|
|
|
-; copy the message itself
|
|
- @@:
|
|
- lodsb
|
|
- test al, al
|
|
- jz @f
|
|
- cmp al, 13
|
|
- je @f
|
|
- cmp al, 10
|
|
- je @f
|
|
- stosb
|
|
- jmp @r
|
|
- @@:
|
|
+ inc ecx ; +1 for a space character after the nickname/channel
|
|
|
|
-; end of message
|
|
- mov al, 0x01
|
|
- stosb
|
|
- mov ax, 0x0a0d
|
|
- stosw
|
|
+ mov ebx, [user_command.size] ; total_length
|
|
+ sub ebx, ecx ; total_length - ("nickname/channel length" + 1)
|
|
+ sub ebx, 6 ; ^ - ("/ctcp " length) = real_message_length
|
|
|
|
-; now print to the window
|
|
+ push edi
|
|
+
|
|
+ mov edi, esi
|
|
+ add edi, ebx
|
|
+
|
|
+ call change_my_msg ; expand/shift user message, if selected
|
|
+
|
|
+ mov dword[edi], 0x00000a0d ; terminate the line
|
|
+
|
|
+ pop edi ebx ecx
|
|
+
|
|
+ push esi esi
|
|
+
|
|
+; print to local window
|
|
if TIMESTAMP
|
|
call print_timestamp
|
|
end if
|
|
@@ -556,7 +1180,7 @@ cmd_usr_ctcp:
|
|
mov esi, ctcp_header
|
|
call print_asciiz
|
|
|
|
- mov esi, user_command+6
|
|
+ mov esi, packetbuf+8
|
|
mov bl, ' '
|
|
call print_string
|
|
|
|
@@ -568,11 +1192,39 @@ cmd_usr_ctcp:
|
|
|
|
pop esi
|
|
call print_asciiz
|
|
+ pop esi
|
|
|
|
- mov al, 10
|
|
- call print_char
|
|
+; encrpt user message, if selected
|
|
+
|
|
+ cmp byte[crpt_state], 0
|
|
+ je .dont_crpt_my_msg
|
|
+
|
|
+ ; pointer is already at esi
|
|
+ call crpt_my_msg
|
|
+
|
|
+ .dont_crpt_my_msg:
|
|
+
|
|
+; copy the message itself
|
|
+ @@:
|
|
+ lodsb
|
|
+ test al, al
|
|
+ jz @f
|
|
+ cmp al, 13
|
|
+ je @f
|
|
+ cmp al, 10
|
|
+ je @f
|
|
+ stosb
|
|
+ jmp @r
|
|
+ @@:
|
|
+
|
|
+; end of message
|
|
+ mov al, 0x01
|
|
+ stosb
|
|
+ mov ax, 0x0a0d
|
|
+ stosw
|
|
+
|
|
+; now send it to the server
|
|
|
|
-; now send it away
|
|
lea esi, [edi - packetbuf] ; calculate length
|
|
mcall send, [socketnum], packetbuf, , 0 ; and finally send to server
|
|
.fail:
|
|
@@ -607,25 +1259,26 @@ cmd_usr_me:
|
|
mov al, 'N'
|
|
stosb
|
|
|
|
-; copy the message itself (including first space)
|
|
- mov esi, user_command+3
|
|
- @@:
|
|
- lodsb
|
|
- cmp al, 13
|
|
- je @f
|
|
- stosb
|
|
- jmp @r
|
|
- @@:
|
|
+; expand/shift user message, if selected
|
|
|
|
-; end of CTCP message
|
|
- mov al, 0x01
|
|
- stosb
|
|
- mov ax, 0x0a0d
|
|
- stosw
|
|
+ mov esi, user_command+4 ; skip "/me "
|
|
|
|
-; now send it to the server
|
|
- lea esi, [edi - packetbuf] ; calculate length
|
|
- mcall send, [socketnum], packetbuf, , 0 ; and finally send to server
|
|
+ push ebx
|
|
+ xor ebx, ebx
|
|
+
|
|
+ mov ebx, [user_command.size] ; total_length
|
|
+ sub ebx, 4 ; ^ - ("/me " length) = real_message_length
|
|
+
|
|
+ push edi
|
|
+
|
|
+ mov edi, esi
|
|
+ add edi, ebx
|
|
+
|
|
+ call change_my_msg ; expand/shift user message, if selected
|
|
+
|
|
+ mov dword[edi], 0x00000a0d ; terminate the line
|
|
+
|
|
+ pop edi ebx
|
|
|
|
; print to local window
|
|
if TIMESTAMP
|
|
@@ -645,6 +1298,36 @@ cmd_usr_me:
|
|
mov al, 10
|
|
call print_char
|
|
|
|
+; encrpt user message, if selected
|
|
+
|
|
+ cmp byte[crpt_state], 0
|
|
+ je .dont_crpt_my_msg
|
|
+
|
|
+ mov esi, user_command+4
|
|
+ call crpt_my_msg
|
|
+
|
|
+ .dont_crpt_my_msg:
|
|
+
|
|
+; copy the message itself (including first space)
|
|
+ mov esi, user_command+3
|
|
+ @@:
|
|
+ lodsb
|
|
+ cmp al, 13
|
|
+ je @f
|
|
+ stosb
|
|
+ jmp @r
|
|
+ @@:
|
|
+
|
|
+; end of CTCP message
|
|
+ mov al, 0x01
|
|
+ stosb
|
|
+ mov ax, 0x0a0d
|
|
+ stosw
|
|
+
|
|
+; now send it to the server
|
|
+ lea esi, [edi - packetbuf] ; calculate length
|
|
+ mcall send, [socketnum], packetbuf, , 0 ; and finally send to server
|
|
+
|
|
ret
|
|
|
|
|
|
--
|
|
2.52.0
|
|
|