Skip to content

Commit b589759

Browse files
author
Coachonko
committedAug 1, 2024
Explain BufferedReader situation vlang/v#21975
1 parent 29d86e1 commit b589759

File tree

1 file changed

+111
-12
lines changed

1 file changed

+111
-12
lines changed
 

‎src/protocol.v

+111-12
Original file line numberDiff line numberDiff line change
@@ -4,24 +4,36 @@ import arrays
44
import os
55
import io
66
import math.big
7-
import crypto.cipher
7+
// import crypto.cipher
88
import x.crypto.chacha20
99
import crypto.sha256
1010
import net
1111

12-
const plugin_list = 'Srp256,Srp' // LegacyAuth not supported
12+
const plugin_list = 'Srp256,Srp'
1313
const buffer_len = 1024
1414
const max_char_length = 32767
1515
const blob_segment_size = 32000
1616

17+
const low_priority_todo = 'https://github.com/Coachonko/firebird/blob/pending/TODO.md#low-priority'
18+
const legacy_auth_error = 'LegacyAuth is not supported: ${low_priority_todo}'
19+
const arc4_error = 'Arc4 wire encryption plugin is not supported: ${low_priority_todo}'
20+
1721
struct WireChannel {
1822
mut:
1923
conn net.TcpConn
2024
reader &io.BufferedReader
25+
// The firebird protocol expects that we are in control of when the writing is flushed.
26+
// In some situations it is required that flushing is deferred.
27+
// io.BufferedWriter doesn't exist
28+
// https://github.com/vlang/v/issues/21975
2129
// writer &io.BufferedWriter
22-
plugin string
23-
crypto_reader &cipher.Stream
24-
crypto_writer &cipher.Stream
30+
plugin string
31+
// crypto_reader and crypto_writer should implement cipher.Stream
32+
// This allows to use any supported stream cipher
33+
// chacha20.Cipher and rc4.Cipher implement the cipher.Stream interface wrong.
34+
// https://github.com/vlang/v/issues/21973
35+
crypto_reader &chacha20.Cipher // &cipher.Stream
36+
crypto_writer &chacha20.Cipher // &cipher.Stream
2537
}
2638

2739
fn new_wire_channel(conn net.TcpConn) &WireChannel {
@@ -39,18 +51,105 @@ fn new_wire_channel(conn net.TcpConn) &WireChannel {
3951

4052
fn (mut c WireChannel) set_crypt_key(plugin string, session_key []u8, nonce []u8) ! {
4153
c.plugin = plugin
54+
if plugin == 'Arc4' {
55+
return error(firebird.arc4_error)
56+
}
57+
4258
if plugin == 'ChaCha' {
4359
mut digest := sha256.new()
4460
digest.write(session_key)!
4561
key := digest.sum([]u8{})
46-
c.crypto_reader = chacha20.new_cipher(key, nonce)! // https://github.com/vlang/v/issues/21973
62+
c.crypto_reader = chacha20.new_cipher(key, nonce)!
4763
c.crypto_writer = chacha20.new_cipher(key, nonce)!
48-
} else if plugin == 'Arc4' {
49-
return error('Arc4 wire encryption plugin is not supported: https://github.com/Coachonko/firebird/blob/pending/TODO.md#low-priority')
50-
} else {
51-
return error('Unknown wire encryption plugin name: ${plugin}')
5264
}
53-
return
65+
66+
return error('Unknown wire encryption plugin name: ${plugin}')
67+
}
68+
69+
fn (mut c WireChannel) read(mut buf []u8) !int {
70+
if c.plugin != '' {
71+
mut src := []u8{}
72+
n := c.reader.read(mut src)!
73+
if c.plugin == 'Arc4' {
74+
return error(firebird.arc4_error)
75+
}
76+
77+
if c.plugin == 'ChaCha' {
78+
c.crypto_reader.xor_key_stream(mut buf, src[0..n])
79+
}
80+
81+
return n
82+
}
83+
84+
return c.reader.read(mut buf)
85+
}
86+
87+
fn (mut c WireChannel) write(buf []u8) !int {
88+
return c.conn.write(buf)!
89+
}
90+
91+
// fn (mut c WireChannel) write(buf []u8) !int {
92+
// if c.plugin != '' {
93+
// mut dst := []u8{}
94+
// if c.plugin == 'Arc4' {
95+
// return error(firebird.arc4_error)
96+
// }
97+
98+
// if c.plugin == 'ChaCha' {
99+
// c.crypto_writer.xor_key_stream(mut dst, buf)
100+
// }
101+
102+
// mut written := 0
103+
// for written < buf.len {
104+
// written += c.writer.write(dst[written..])!
105+
// }
106+
// return written
107+
// }
108+
109+
// return c.writer.write(mut buf)
110+
// }
111+
112+
// fn (mut c WireChannel) flush() ! {
113+
// c.writer.flush()!
114+
// }
115+
116+
fn (mut c WireChannel) close() ! {
117+
c.conn.close()!
118+
}
119+
120+
struct WireProtocol {
121+
buf []u8
122+
123+
conn WireChannel
124+
db_handle i32
125+
addr string
126+
127+
protocol_version i32
128+
accept_architecture i32
129+
accept_type i32
130+
lazy_response_count int
131+
132+
plugin_name string
133+
user string
134+
password string
135+
auth_data []u8
136+
137+
charset string
138+
charset_byte_len int
139+
140+
timezone string
141+
}
142+
143+
fn new_wire_protocol(addr string, timezone string) !&WireProtocol {
144+
conn := net.dial_tcp(addr)!
145+
return &WireProtocol{
146+
buf: []u8{}
147+
conn: new_wire_channel(conn)
148+
addr: addr
149+
charset: 'UTF8'
150+
charset_byte_len: 4
151+
timezone: timezone
152+
}
54153
}
55154

56155
fn user_identification(user string, auth_plugin_name string, wire_crypt bool, client_public big.Integer) []u8 {
@@ -94,7 +193,7 @@ fn user_identification(user string, auth_plugin_name string, wire_crypt bool, cl
94193
}
95194

96195
if auth_plugin_name == 'Legacy_Auth' {
97-
panic('Unsupported plugin: ${auth_plugin_name}')
196+
panic(firebird.legacy_auth_error)
98197
}
99198
panic('Unknown plugin name: ${auth_plugin_name}')
100199
}

0 commit comments

Comments
 (0)
Please sign in to comment.