Created
June 3, 2022 17:58
-
-
Save duanebester/0e40bee407072a213bf26ae264edb538 to your computer and use it in GitHub Desktop.
Talk to Postgres w/ Unison
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
use .base | |
-- SQL password message: concat('md5', md5(concat(md5(concat(password, username)), random-salt))) | |
-- "md58393de45eea6f814e37f41f02540710c" | |
calculatePassword: Text -> Text -> Bytes -> Text | |
calculatePassword username password salt = | |
use md5 md5EncodeAscii md5Encode | |
userpassMd5 = md5EncodeAscii (password ++ username) | |
use Text toUtf8 | |
userpassMd5Bytes = (toUtf8 userpassMd5) | |
combinedMd5Bytes = md5Encode (userpassMd5Bytes ++ salt) | |
use md5.utils bytesToHexText | |
hexText = bytesToHexText combinedMd5Bytes | |
pw = "md5" ++ hexText | |
pw | |
buildStartupMessage: Text -> Text -> Bytes | |
buildStartupMessage username database = | |
use Text size | |
use Bytes encodeNat32be | |
len = (encodeNat32be ((size username) + (size database) + 16 + 4 + 4 + 1)) | |
startup = (encodeNat32be 196608) | |
use Text toUtf8 | |
u1 = (toUtf8 "user\0") | |
u2 = (toUtf8 (username ++ "\0")) | |
d1 = (toUtf8 "database\0") | |
d2 = (toUtf8 (database ++ "\0")) | |
use Bytes fromList | |
b = (fromList [0]) | |
bs = (len ++ startup ++ u1 ++ u2 ++ d1 ++ d2 ++ b) | |
bs | |
buildPasswordMessage: Text -> Bytes | |
buildPasswordMessage password = | |
use Text size | |
use Bytes encodeNat32be | |
len = (encodeNat32be ((size password) + 4 + 1)) | |
use Bytes fromList | |
pwTag = (fromList [112]) | |
data = (Text.toUtf8 (password ++ "\0")) | |
bs = (pwTag ++ len ++ data) | |
bs | |
unique type BackendMessage | |
= { tag: Nat, | |
length: Nat, | |
data: Bytes } | |
recvMessage: Socket ->{Exception, IO} BackendMessage | |
recvMessage socket = | |
tagByte = io.socketReceive socket 1 | |
tag = (Optional.getOrElse 0 (Bytes.at 0 tagByte)) | |
lenBytes = io.socketReceive socket 4 | |
lenMaybe = (Bytes.decodeNat32be lenBytes) | |
len = match lenMaybe with | |
None -> 0 | |
Some (x, y) -> x | |
use Nat drop | |
remaining = drop len 4 | |
remBytes = io.socketReceive socket remaining | |
BackendMessage tag len remBytes | |
host = HostName "localhost" | |
port = ServiceName "5432" | |
program : '{IO, Exception} () | |
program = 'let | |
socket = io.clientSocket host port | |
printLine "Sending Startup Message" | |
socketSend socket (buildStartupMessage "jimmy" "world") | |
recv = recvMessage socket | |
use Text ++ | |
use Text join | |
use Nat toText | |
printLine "Receiving Message" | |
printLine ("Tag: " ++ (toText (BackendMessage.tag recv))) | |
printLine ("Length: " ++ (toText (BackendMessage.length recv))) | |
printLine ("Data: " ++ (join ", " (List.map (elem -> (toText elem)) (Bytes.toList (BackendMessage.data recv))))) | |
pw = calculatePassword "jimmy" "banana" (Bytes.drop 4 (BackendMessage.data recv)) | |
printLine "Sending Password Message" | |
socketSend socket (buildPasswordMessage pw) | |
recv2 = recvMessage socket | |
printLine "Receiving Message" | |
printLine ("Tag: " ++ (toText (BackendMessage.tag recv2))) | |
printLine ("Length: " ++ (toText (BackendMessage.length recv2))) | |
printLine ("Data: " ++ (join ", " (List.map (elem -> (toText elem)) (Bytes.toList (BackendMessage.data recv2))))) | |
base.io.closeSocket socket |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Docker Compose file for reference: