row editing

This commit is contained in:
Mark Gregory
2026-10-21 10:21:27 +01:00
parent 2229238e52
commit 3f9f572434
+42 -9
View File
@@ -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
}
}