- socket_buffer_left = 0; /* Global, used to read more than a line but return by line */
- while (cont) {
- if (dc_gets(buffer, sizeof(buffer), fd) == NULL)
- OUT("authentication socket read error or premature eof");
- p = buffer + Ustrlen(buffer) - 1;
- if (*p != '\n') {
- OUT("authentication socket protocol line too long");
- }
- *p = '\0';
- HDEBUG(D_auth) debug_printf("received: %s\n", buffer);
- nargs = strcut(buffer, args, sizeof(args) / sizeof(args[0]));
- /* HDEBUG(D_auth) debug_strcut(args, nargs, sizeof(args) / sizeof(args[0])); */
-
- /* Code below rewritten by Kirill Miazine (km@krot.org). Only check commands that
- Exim will need. Original code also failed if Dovecot server sent unknown
- command. E.g. COOKIE in version 1.1 of the protocol would cause troubles. */
- /* pdp: note that CUID is a per-connection identifier sent by the server,
- which increments at server discretion.
- By contrast, the "id" field of the protocol is a connection-specific request
- identifier, which needs to be unique per request from the client and is not
- connected to the CUID value, so we ignore CUID from server. It's purely for
- diagnostics. */
- if (Ustrcmp(args[0], US"VERSION") == 0) {
- CHECK_COMMAND("VERSION", 2, 2);
- if (Uatoi(args[1]) != VERSION_MAJOR)
- OUT("authentication socket protocol version mismatch");
- } else if (Ustrcmp(args[0], US"MECH") == 0) {
- CHECK_COMMAND("MECH", 1, INT_MAX);
- have_mech_line = TRUE;
- if (strcmpic(US args[1], ablock->public_name) == 0)
- found = TRUE;
- } else if (Ustrcmp(args[0], US"SPID") == 0) {
- /* Unfortunately the auth protocol handshake wasn't designed well
- to differentiate between auth-client/userdb/master. auth-userdb
- and auth-master send VERSION + SPID lines only and nothing
- afterwards, while auth-client sends VERSION + MECH + SPID +
- CUID + more. The simplest way that we can determine if we've
- connected to the correct socket is to see if MECH line exists or
- not (alternatively we'd have to have a small timeout after SPID
- to see if CUID is sent or not). */
- if (!have_mech_line)
- OUT("authentication socket type mismatch (connected to auth-master instead of auth-client)");
- } else if (Ustrcmp(args[0], US"DONE") == 0) {
- CHECK_COMMAND("DONE", 0, 0);
- cont = 0;
- }
- }
-
- if (!found) {
- auth_defer_msg = string_sprintf("Dovecot did not advertise mechanism \"%s\" to us", ablock->public_name);
- goto out;
- }