June 2018 Update

This commit is contained in:
Ingy döt Net 2018-06-22 20:57:24 +00:00
parent ba8067c3b7
commit 22f33d4004
5278 changed files with 84726 additions and 14379 deletions

View file

@ -0,0 +1,48 @@
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)

View file

@ -0,0 +1,101 @@
// Version 1.2.41
import java.sql.Connection
import java.sql.DriverManager
import java.sql.ResultSet
import java.security.MessageDigest
import java.security.SecureRandom
import java.math.BigInteger
class UserManager {
private lateinit var dbConnection: Connection
private fun md5(message: String): String {
val hexString = StringBuilder()
val bytes = message.toByteArray()
val md = MessageDigest.getInstance("MD5")
val dig = md.digest(bytes)
for (i in 0 until dig.size) {
val hex = (0xff and dig[i].toInt()).toString(16)
if (hex.length == 1) hexString.append('0')
hexString.append(hex)
}
return hexString.toString()
}
fun connectDB(host: String, port: Int, db: String, user: String, pwd: String) {
Class.forName("com.mysql.jdbc.Driver")
dbConnection = DriverManager.getConnection(
"jdbc:mysql://$host:$port/$db", user, pwd
)
}
fun createUser(user: String, pwd: String): Boolean {
val random = SecureRandom()
val salt = BigInteger(130, random).toString(16)
val insert = "INSERT INTO users " +
"(username, pass_salt, pass_md5) " +
"VALUES (?, ?, ?)"
try {
val pstmt = dbConnection.prepareStatement(insert)
with (pstmt) {
setString(1, user)
setString(2, salt)
setString(3, md5(salt + pwd))
val rowCount = executeUpdate()
close()
if (rowCount == 0) return false
}
return true
}
catch (ex: Exception) {
return false
}
}
fun authenticateUser(user: String, pwd: String): Boolean {
val select = "SELECT pass_salt, pass_md5 FROM users WHERE username = ?"
lateinit var res: ResultSet
try {
val pstmt = dbConnection.prepareStatement(select)
with (pstmt) {
setString(1, user)
res = executeQuery()
res.next() // assuming that username is unique
val passSalt = res.getString(1)
val passMD5 = res.getString(2)
close()
return passMD5 == md5(passSalt + pwd)
}
}
catch (ex: Exception) {
return false
}
finally {
if (!res.isClosed) res.close()
}
}
fun closeConnection() {
if (!dbConnection.isClosed) dbConnection.close()
}
}
fun main(args: Array<String>) {
val um = UserManager()
with (um) {
try {
connectDB("localhost", 3306, "test", "root", "admin")
if (createUser("johndoe", "test")) println("User created")
if (authenticateUser("johndoe", "test")) {
println("User authenticated")
}
}
catch(ex: Exception) {
ex.printStackTrace()
}
finally {
closeConnection()
}
}
}