3 ** Copyright 1998 - 2006 Double Precision, Inc. See COPYING for
4 ** distribution information.
7 #include "courier_auth_config.h"
8 #include "random128/random128.h"
9 #include "courierauthsasl.h"
19 extern char *strdupdefdomain(const char *userid
, const char *s1
,
20 const char *s2
, const char *s3
);
22 int authsasl_cram(const char *method
, const char *initresponse
,
23 char *(*getresp
)(const char *, void *),
28 const char *randtoken
;
29 char hostnamebuf
[256];
31 char *challenge_base64
;
37 if (initresponse
&& *initresponse
)
39 if (write(2, "authsasl_cram: invalid request.\n", 32) < 0)
40 ; /* ignore gcc warning */
41 return (AUTHSASL_ERROR
);
44 randtoken
=random128();
46 if (gethostname(hostnamebuf
, sizeof(hostnamebuf
)-1))
47 strcpy(hostnamebuf
, "cram");
49 challenge
=malloc(strlen(randtoken
)+strlen(hostnamebuf
)
54 return (AUTHSASL_ERROR
);
56 strcat(strcat(strcat(strcat(strcpy(challenge
, "<"),
57 randtoken
), "@"), hostnamebuf
), ">");
59 challenge_base64
=authsasl_tobase64(challenge
, -1);
61 if (!challenge_base64
)
64 return (AUTHSASL_ERROR
);
67 response
=getresp(challenge_base64
, callback_arg
);
70 free(challenge_base64
);
71 return (AUTHSASL_ERROR
);
76 free(challenge_base64
);
78 return (AUTHSASL_ABORTED
);
81 /* If DEFDOMAIN is set, pick apart the response and reassemble
82 * it, potentially with a default domain appended to the username */
83 q
=getenv("DEFDOMAIN");
87 if ( (plen
= authsasl_frombase64(response
)) > 0 &&
88 (response
[plen
]=0, (s
= strchr(response
, ' ')) != 0) &&
89 (*s
++ = 0, (t
= strdupdefdomain(response
, " ", s
, "")) != 0) )
91 r
= authsasl_tobase64(t
, -1);
95 if ((response
= r
) == 0)
97 free(challenge_base64
);
98 return (AUTHSASL_ERROR
);
102 chrsp
=malloc(strlen(challenge_base64
)+strlen(response
)+3);
105 free(challenge_base64
);
108 return (AUTHSASL_ERROR
);
111 strcat(strcat(strcat(strcpy(chrsp
, challenge_base64
), "\n"),
113 free(challenge_base64
);
116 if ( (*authtype
=malloc(strlen(method
)+1)) == 0)
120 return (AUTHSASL_ERROR
);
122 strcpy( *authtype
, method
);
125 for (chrsp
= *authtype
; *chrsp
; chrsp
++)
126 *chrsp
= tolower( (int)(unsigned char)*chrsp
);
128 return (AUTHSASL_OK
);