/* * kerberos.c -- Kerberos authentication (see RFC 1731). * * For license terms, see the file COPYING in this directory. */ #include "config.h" #ifdef KERBEROS_V4 #include #include #include #if defined(STDC_HEADERS) #include #endif #include "fetchmail.h" #include "socket.h" #include "kerberos.h" #include #include /* for htonl/ntohl */ #include "i18n.h" #if SIZEOF_INT == 4 typedef int int32; #elif SIZEOF_SHORT == 4 typedef short int32; #elif SIZEOF_LONG == 4 typedef long int32; #else #error Cannot deduce a 32-bit-type #endif int do_rfc1731(int sock, char *command, char *truename) /* authenticate as per RFC1731 -- note 32-bit integer requirement here */ { int result = 0, len; char buf1[4096], buf2[4096]; union { int32 cint; char cstr[4]; } challenge1, challenge2; char srvinst[INST_SZ]; char *p; char srvrealm[REALM_SZ]; KTEXT_ST authenticator; CREDENTIALS credentials; char tktuser[MAX_K_NAME_SZ+1+INST_SZ+1+REALM_SZ+1]; char tktinst[INST_SZ]; char tktrealm[REALM_SZ]; des_cblock session; des_key_schedule schedule; gen_send(sock, "%s KERBEROS_V4", command); /* The data encoded in the first ready response contains a random * 32-bit number in network byte order. The client should respond * with a Kerberos ticket and an authenticator for the principal * "imap.hostname@realm", where "hostname" is the first component * of the host name of the server with all letters in lower case * and where "realm" is the Kerberos realm of the server. The * encrypted checksum field included within the Kerberos * authenticator should contain the server provided 32-bit number * in network byte order. */ if ((result = gen_recv(sock, buf1, sizeof buf1)) != 0) { return result; } len = from64tobits(challenge1.cstr, buf1, sizeof(challenge1.cstr)); if (len < 0) { report(stderr, GT_("could not decode initial BASE64 challenge\n")); return PS_AUTHFAIL; } /* this patch by Dan Root solves an endianess * problem. */ { char tmp[4]; *(int *)tmp = ntohl(*(int *) challenge1.cstr); memcpy(challenge1.cstr, tmp, sizeof(tmp)); } /* Client responds with a Kerberos ticket and an authenticator for * the principal "imap.hostname@realm" where "hostname" is the * first component of the host name of the server with all letters * in lower case and where "realm" is the Kerberos realm of the * server. The encrypted checksum field included within the * Kerberos authenticator should contain the server-provided * 32-bit number in network byte order. */ strncpy(srvinst, truename, (sizeof srvinst)-1); srvinst[(sizeof srvinst)-1] = '\0'; for (p = srvinst; *p; p++) { if (isupper((unsigned char)*p)) { *p = tolower((unsigned char)*p); } } strncpy(srvrealm, (char *)krb_realmofhost(srvinst), (sizeof srvrealm)-1); srvrealm[(sizeof srvrealm)-1] = '\0'; if ((p = strchr(srvinst, '.')) != NULL) { *p = '\0'; } result = krb_mk_req(&authenticator, "imap", srvinst, srvrealm, 0); if (result) { report(stderr, "krb_mq_req: %s\n", krb_g
../build/fetchmail-man.html