MySQL with SASL
This is an experiment to add SASL authentication, security and authorization to the MySQL wire protocol. It is in a very alpha stage. It may even turn into gssapi only to fix principal name meanings.
|Other mysql releases|
Notes on kerberizing MySQL
There is existing support for SSL and compression, which can be leveraged to fit with SASL framing.
- When the client connects to the server, the server sends a protocol packet, and the client will quit if it doesn't exactly understand the protocol version PROTOCOL_VERSION (defined in configure.in as 10)
- The file sql/net_serv.cc contains the low-level packet i/o routines. There is a 'compressed' packet protocol and an uncompressed packet protocol.
+------------+---------+ | net-header | payload | +------------+---------+ +------------+-------------+---------+ | net-header | comp-header | payload | +------------+-------------+---------+
In both, the 4-byte net-header consists of
+------+------+------+--------+ net-header: | len0 | len1 | len2 | pkt_nr | +------+------+------+--------+
where len is the number of bytes in the the packet (including all headers), and pkt_nr is an 8-bit sequence number that increments by one for each packet.
+-------+-------+-------+ comp-header: | clen0 | clen1 | clen2 | +-------+-------+-------+
where clen is the length of the packet after decompression.
Compression is negotiated in the first packet exchange.
MySQL has a virtual network I/O abstraction. This exists apparently to support SSL, but would be the right place to support GSSAPI. (See the vio directory and include/violite.h)
CLI_MYSQL_REAL_CONNECT in client.c
contains all the hairy client logic to connect,
authenticate and negotiate compression.
On the server side, the function
in sql_parse.cc constructs the first packet
and checks the reply. These are the ideal
places to insert GSSAPI negotiation.
Format of the first packet (server -> client)
28 00 00 - packet length (40 bytes) 00 - packet sequence number (first packet is 0) 0a - protocol version (10) 332e 3233 2e35 3800 - "3.23.58\0" (server version) c1020000 - thread ID 0x2c1 512e 3047 565a 4277 00 - "Q.0GVZBw\0" 8-char '323' scramble code 2c20 - 2 bytes of server_capabilities (see CLIENT_* below) 0802 0000 0000 0000 0000 0000 0000 0000 - 16 bytes of optional capability code: 1st byte is server language 2nd+3rd bytes are server status word (lsb) rest appear reserved xxx... - remainder of packet is further 12 bytes of scramble code when 4.1 authentication is used.
Flags used when negotiating capabilities (capability code):
#define CLIENT_LONG_PASSWORD 0x0001 /* new more secure passwords */ #define CLIENT_FOUND_ROWS 0x0002 /* Found instead of affected rows */ #define CLIENT_LONG_FLAG 0x0004 /* Get all column flags */ #define CLIENT_CONNECT_WITH_DB 0x0008 /* One can specify db on connect */ #define CLIENT_NO_SCHEMA 0x0010 /* Don't allow database.table.column */ #define CLIENT_COMPRESS 0x0020 /* Can use compression protocol */ #define CLIENT_ODBC 0x0040 /* Odbc client */ #define CLIENT_LOCAL_FILES 0x0080 /* Can use LOAD DATA LOCAL */ #define CLIENT_IGNORE_SPACE 0x0100 /* Ignore spaces before '(' */ #define CLIENT_PROTOCOL_41 0x0200 /* New 4.1 protocol */ #define CLIENT_INTERACTIVE 0x0400 /* This is an interactive client */ #define CLIENT_SSL 0x0800 /* Switch to SSL after handshake */ #define CLIENT_IGNORE_SIGPIPE 0x1000 /* IGNORE sigpipes */ #define CLIENT_TRANSACTIONS 0x2000 /* Client knows about transactions */ #define CLIENT_RESERVED 0x4000 /* Old flag for 4.1 protocol */ #define CLIENT_SECURE_CONNECTION 0x8000 /* New 4.1 authentication */ #define CLIENT_MULTI_STATEMENTS 0xffff /* Enable/disable multi-stmt support */ #define CLIENT_MULTI_RESULTS 131072 /* Enable/disable multi-results */ #define CLIENT_REMEMBER_OPTIONS (((ulong) 1) << 31)
Format of first reply packet (client -> server)
if PROTOCOL_41 is *not* set: xxxx - 16-bit client flag showing what options are supported xxxxxx - 24-bit maximum packet size
xxxxxxxx - 32-bit client flag showing options supported xxxxxxxx - 32-bit maximum packet size xx - 8-bit charset selector pad - 27 bytes of nul padding to make packet 32 bytes long.
Immediately after this packet is sent, SSL will commence (if CLIENT_SSL of the client flag is set).
(This client behaviour seems to be the same in mysql 5.0 alpha)
- The server keeps the current user & host in the
THDclass (see sql/sql_class.h)
- The ACL mechanisms provide for matching of
users by wildcards. user
host. This may have to be changed if we want to specify principals (eg
john@COMPANY.COM). I think the best way is to extend the
GRANT ... REQUIREsyntax so that you can write
GRANT ALL PRIVILEGES ON test.* TO 'user'@'realm' REQUIRE GSSAPI;Such user ACLs are stored in class ACL_USER in sql/sql_acl.h, and make use of the
SSL_typeenum defined in include/violite.h
— David Leonard