You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
129 lines
3.2 KiB
129 lines
3.2 KiB
|
|
function queue_encrypted_bytes(client, buf)
|
|
# println("Adding $(length(buf)) for a total of $(length(buf) + length(client.write_buf))")
|
|
append!(client.write_buf, buf)
|
|
end
|
|
|
|
function do_ssl_handshake(client)
|
|
n = SSL_handshake(client)
|
|
status = ssl_status(client, n)
|
|
if status in (SSL_WANT_READ, SSL_WANT_WRITE)
|
|
while true
|
|
(n, buf) = bio_read(client)
|
|
# println("bio_read: $(n)")
|
|
if n > 0
|
|
queue_encrypted_bytes(client, buf)
|
|
elseif !bio_should_retry(client.wbio)
|
|
return -1
|
|
end
|
|
if n <= 0
|
|
break
|
|
end
|
|
end
|
|
end
|
|
# println("End of ssl handshake")
|
|
return status
|
|
end
|
|
|
|
function send_unencrypted_bytes(client, buf)
|
|
append!(client.encrypt_buf, buf)
|
|
end
|
|
|
|
function do_encrypt(client)
|
|
ssl_init_finished(client) || return 0
|
|
|
|
while length(client.encrypt_buf) > 0
|
|
n = ssl_write(client, client.encrypt_buf)
|
|
status = ccall((:SSL_get_error, libssl), SSL_ERRORS, (Ptr{Cvoid}, Cint),
|
|
client.ssl, n)
|
|
if n > 0
|
|
splice!(client.encrypt_buf, 1:n)
|
|
while true
|
|
(n, buf) = bio_read(client)
|
|
if n > 0
|
|
queue_encrypted_bytes(client, buf)
|
|
elseif !bio_should_retry(client.wbio)
|
|
return -1
|
|
end
|
|
n > 0 || break
|
|
end
|
|
end
|
|
if status in (SSL_ERROR, SSL_SYSCALL)
|
|
@warn "SSL ERROR"
|
|
return -1
|
|
end
|
|
if n == 0
|
|
break
|
|
end
|
|
end
|
|
return 0
|
|
end
|
|
|
|
|
|
function on_read_cb(client, buffer)
|
|
idx = 1
|
|
len = length(buffer)
|
|
while len > 0
|
|
n = bio_write!(client, buffer[idx:end])
|
|
if n <= 0
|
|
return -1
|
|
end
|
|
idx += n
|
|
len -= n
|
|
|
|
if ! ssl_init_finished(client)
|
|
# println("SSL not finished yet")
|
|
if (do_ssl_handshake(client) == -1)
|
|
return -1
|
|
end
|
|
if !ssl_init_finished(client)
|
|
return 0
|
|
end
|
|
end
|
|
# println("NOW IT FINISHED\n")
|
|
while true
|
|
(n, buf) = read(client)
|
|
if n > 0
|
|
client.io_on_read(buf[1:n])
|
|
else
|
|
break
|
|
end
|
|
end
|
|
status = ssl_status(client, n)
|
|
if status in (SSL_WANT_READ, SSL_WANT_WRITE)
|
|
while true
|
|
(n, buf) = bio_read(client)
|
|
if n > 0
|
|
queue_encrypted_bytes(client, buf)
|
|
elseif !bio_should_retry(client.wbio)
|
|
return -1
|
|
end
|
|
n < 0 && break
|
|
end
|
|
end
|
|
if status in (SSL_ERROR, SSL_SYSCALL)
|
|
return -1
|
|
end
|
|
end
|
|
return 0
|
|
end
|
|
|
|
function do_sock_read(client::SSLClient)
|
|
buf = readavailable(client.sock)
|
|
if length(buf) > 0
|
|
return on_read_cb(client, buf)
|
|
else
|
|
return -1
|
|
end
|
|
end
|
|
|
|
function do_sock_write(client::SSLClient)
|
|
n = write(client.sock, client.write_buf)
|
|
# println("Written to the client: $n")
|
|
if n > 0
|
|
splice!(client.write_buf, 1:n)
|
|
return 0
|
|
else
|
|
return -1
|
|
end
|
|
end
|
|
|