49 lines
1.9 KiB
Plaintext
49 lines
1.9 KiB
Plaintext
using MySQL
|
|
using Nettle # for md5
|
|
|
|
function connect_db(uri, user, pw, dbname)
|
|
mydb = mysql_connect(uri, user, pw, dbname)
|
|
|
|
const command = """CREATE TABLE IF NOT EXISTS users (
|
|
userid INT PRIMARY KEY AUTO_INCREMENT,
|
|
username VARCHAR(32) UNIQUE KEY NOT NULL,
|
|
pass_salt tinyblob NOT NULL,
|
|
-- a string of 16 random bytes
|
|
pass_md5 tinyblob NOT NULL
|
|
-- binary MD5 hash of pass_salt concatenated with the password
|
|
);"""
|
|
mysql_execute(mydb, command)
|
|
mydb
|
|
end
|
|
|
|
function create_user(dbh, user, pw)
|
|
mysql_stmt_prepare(dbh, "INSERT IGNORE INTO users (username, pass_salt, pass_md5) values (?, ?, ?);")
|
|
salt = join([Char(c) for c in rand(UInt8, 16)], "")
|
|
passmd5 = digest("md5", salt * user)
|
|
mysql_execute(dbh, [MYSQL_TYPE_VARCHAR, MYSQL_TYPE_VARCHAR, MYSQL_TYPE_VARCHAR], [user, salt, passmd5])
|
|
end
|
|
|
|
function addusers(dbh, userdict)
|
|
for user in keys(userdict)
|
|
create_user(dbh, user, userdict[user])
|
|
end
|
|
end
|
|
|
|
"""
|
|
authenticate_user
|
|
Note this returns true if password provided authenticates as correct, false otherwise
|
|
"""
|
|
function authenticate_user(dbh, username, pw)
|
|
mysql_stmt_prepare(dbh, "SELECT pass_salt, pass_md5 FROM users WHERE username = ?;")
|
|
pass_salt, pass_md5 = mysql_execute(dbh, [MYSQL_TYPE_VARCHAR], [username], opformat=MYSQL_TUPLES)[1]
|
|
pass_md5 == digest("md5", pass_salt * username)
|
|
end
|
|
|
|
const users = Dict("Joan" => "joanspw", "John" => "johnspw", "Mary" => "marpw", "Mark" => "markpw")
|
|
const mydb = connect_db("192.168.1.1", "julia", "julia", "mydb")
|
|
|
|
addusers(mydb, users)
|
|
println("""John authenticates correctly: $(authenticate_user(mydb, "John", "johnspw")==false)""")
|
|
println("""Mary does not authenticate with password of 123: $(authenticate_user(mydb, "Mary", "123")==false)""")
|
|
mysql_disconnect(mydb)
|