row editing
This commit is contained in:
@@ -208,7 +208,7 @@ private final class MySQLSocketTransport {
|
||||
init(host: String, port: Int) throws {
|
||||
var hints = addrinfo()
|
||||
hints.ai_family = AF_UNSPEC
|
||||
hints.ai_socktype = Int32(SOCK_STREAM.rawValue)
|
||||
hints.ai_socktype = Int32(SOCK_STREAM)
|
||||
hints.ai_protocol = Int32(IPPROTO_TCP)
|
||||
var addresses: UnsafeMutablePointer<addrinfo>?
|
||||
let result = getaddrinfo(host, String(port), &hints, &addresses)
|
||||
@@ -241,7 +241,7 @@ private final class MySQLSocketTransport {
|
||||
if let ssl {
|
||||
var processed = 0
|
||||
let status = SSLRead(ssl, buffer, count, &processed)
|
||||
if status == errSSLSuccess || (status == errSSLWouldBlock && processed > 0) { return processed }
|
||||
if status == errSecSuccess || (status == errSSLWouldBlock && processed > 0) { return processed }
|
||||
throw MySQLWireError(message: "MySQL TLS read failed (OSStatus \(status))")
|
||||
}
|
||||
let n = Darwin.recv(fd, buffer, count, 0)
|
||||
@@ -253,7 +253,7 @@ private final class MySQLSocketTransport {
|
||||
if let ssl {
|
||||
var processed = 0
|
||||
let status = SSLWrite(ssl, buffer, count, &processed)
|
||||
if status == errSSLSuccess || (status == errSSLWouldBlock && processed > 0) { return processed }
|
||||
if status == errSecSuccess || (status == errSSLWouldBlock && processed > 0) { return processed }
|
||||
throw MySQLWireError(message: "MySQL TLS write failed (OSStatus \(status))")
|
||||
}
|
||||
let n = Darwin.send(fd, buffer, count, 0)
|
||||
@@ -268,7 +268,7 @@ private final class MySQLSocketTransport {
|
||||
// SecureTransport callback connections refer to this retained transport.
|
||||
let connection = Unmanaged.passUnretained(self).toOpaque()
|
||||
var status = SSLSetIOFuncs(context, { connection, data, length in
|
||||
guard let connection, let data, let length else { return errSecParam }
|
||||
|
||||
let transport = Unmanaged<MySQLSocketTransport>.fromOpaque(connection).takeUnretainedValue()
|
||||
let requested = length.pointee
|
||||
let n = Darwin.recv(transport.fd, data, requested, 0)
|
||||
@@ -276,7 +276,7 @@ private final class MySQLSocketTransport {
|
||||
length.pointee = 0
|
||||
return n == 0 ? errSSLClosedGraceful : errSecIO
|
||||
}, { connection, data, length in
|
||||
guard let connection, let data, let length else { return errSecParam }
|
||||
|
||||
let transport = Unmanaged<MySQLSocketTransport>.fromOpaque(connection).takeUnretainedValue()
|
||||
let n = Darwin.send(transport.fd, data, length.pointee, 0)
|
||||
if n > 0 { length.pointee = n; return errSecSuccess }
|
||||
@@ -290,10 +290,43 @@ private final class MySQLSocketTransport {
|
||||
guard status == errSecSuccess else { throw MySQLWireError(message: "TLS peer setup failed (\(status))") }
|
||||
// REQUIRED encrypts but does not authenticate the server. Keep verification
|
||||
// enabled for the verified mode; never silently fall back to REQUIRED.
|
||||
status = SSLSetEnableCertVerify(context, verify)
|
||||
guard status == errSecSuccess else { throw MySQLWireError(message: "TLS verification setup failed (\(status))") }
|
||||
repeat { status = SSLHandshake(context) } while status == errSSLWouldBlock
|
||||
guard status == errSecSuccess else { throw MySQLWireError(message: "MySQL TLS handshake failed (OSStatus \(status))") }
|
||||
// Certificate verification is handled after the TLS handshake.
|
||||
status = SSLSetSessionOption(context, .breakOnServerAuth, true)
|
||||
guard status == errSecSuccess else {
|
||||
throw MySQLWireError(message: "TLS authentication setup failed (\(status))")
|
||||
}
|
||||
|
||||
repeat {
|
||||
status = SSLHandshake(context)
|
||||
} while status == errSSLWouldBlock
|
||||
|
||||
if status == OSStatus(-9841) {
|
||||
if verify {
|
||||
var trust: SecTrust?
|
||||
let trustStatus = SSLCopyPeerTrust(context, &trust)
|
||||
|
||||
guard trustStatus == errSecSuccess, let trust else {
|
||||
throw MySQLWireError(message: "Unable to obtain MySQL server trust")
|
||||
}
|
||||
|
||||
var trustError: CFError?
|
||||
|
||||
guard SecTrustEvaluateWithError(trust, &trustError) else {
|
||||
throw MySQLWireError(
|
||||
message: "MySQL server verification failed: \(trustError?.localizedDescription ?? "untrusted server")"
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
repeat {
|
||||
status = SSLHandshake(context)
|
||||
} while status == errSSLWouldBlock
|
||||
}
|
||||
|
||||
guard status == errSecSuccess else {
|
||||
throw MySQLWireError(message: "MySQL TLS handshake failed (OSStatus \(status))")
|
||||
}
|
||||
|
||||
ssl = context
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user