June 2018 Update
This commit is contained in:
parent
ba8067c3b7
commit
22f33d4004
5278 changed files with 84726 additions and 14379 deletions
|
|
@ -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)
|
||||
|
|
@ -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()
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue