Files
IRCC_Vigenere/kolibrios_v8930_ircc-vigenere.patch
T
2026-01-24 22:34:45 +00:00

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