(create_gsasl_stream,gsasl_replace_streams): Fixed declarations.
(auth_step_base64): New function. A wrapper around gsasl_server_step_base64 to cope with GSASL_TOO_SMALL_BUFFER error code. (auth_gsasl): Use auth_step_base64(). Output any surplus data returned with GSASL_OK code (proposed by Simon Josefsson <jas@extundo.com>)
Showing
1 changed file
with
43 additions
and
7 deletions
... | @@ -22,12 +22,14 @@ | ... | @@ -22,12 +22,14 @@ |
22 | static Gsasl_ctx *ctx; | 22 | static Gsasl_ctx *ctx; |
23 | static Gsasl_session_ctx *sess_ctx; | 23 | static Gsasl_session_ctx *sess_ctx; |
24 | 24 | ||
25 | static void auth_gsasl_capa_init __P((int disable)); | ||
26 | |||
25 | static int | 27 | static int |
26 | create_gsasl_stream (stream_t *newstr, stream_t str, int flags) | 28 | create_gsasl_stream (stream_t *newstr, int fd, int flags) |
27 | { | 29 | { |
28 | int rc; | 30 | int rc; |
29 | 31 | ||
30 | rc = gsasl_stream_create (newstr, str, sess_ctx, flags); | 32 | rc = gsasl_stream_create (newstr, fd, sess_ctx, flags); |
31 | if (rc) | 33 | if (rc) |
32 | { | 34 | { |
33 | syslog (LOG_ERR, _("cannot create SASL stream: %s"), | 35 | syslog (LOG_ERR, _("cannot create SASL stream: %s"), |
... | @@ -47,7 +49,7 @@ create_gsasl_stream (stream_t *newstr, stream_t str, int flags) | ... | @@ -47,7 +49,7 @@ create_gsasl_stream (stream_t *newstr, stream_t str, int flags) |
47 | return RESP_OK; | 49 | return RESP_OK; |
48 | } | 50 | } |
49 | 51 | ||
50 | void | 52 | int |
51 | gsasl_replace_streams (void *self, void *data) | 53 | gsasl_replace_streams (void *self, void *data) |
52 | { | 54 | { |
53 | stream_t *s = data; | 55 | stream_t *s = data; |
... | @@ -60,13 +62,36 @@ gsasl_replace_streams (void *self, void *data) | ... | @@ -60,13 +62,36 @@ gsasl_replace_streams (void *self, void *data) |
60 | return 0; | 62 | return 0; |
61 | } | 63 | } |
62 | 64 | ||
65 | #define AUTHBUFSIZE 512 | ||
66 | |||
67 | static int | ||
68 | auth_step_base64(Gsasl_session_ctx *sess_ctx, char *input, | ||
69 | char **output, size_t *output_len) | ||
70 | { | ||
71 | int rc; | ||
72 | |||
73 | while (1) | ||
74 | { | ||
75 | rc = gsasl_server_step_base64 (sess_ctx, input, *output, *output_len); | ||
76 | |||
77 | if (rc == GSASL_TOO_SMALL_BUFFER) | ||
78 | { | ||
79 | *output_len += AUTHBUFSIZE; | ||
80 | *output = realloc(*output, *output_len); | ||
81 | if (output) | ||
82 | continue; | ||
83 | } | ||
84 | break; | ||
85 | } | ||
86 | return rc; | ||
87 | } | ||
63 | 88 | ||
64 | static int | 89 | static int |
65 | auth_gsasl (struct imap4d_command *command, | 90 | auth_gsasl (struct imap4d_command *command, |
66 | char *auth_type, char *arg, char **username) | 91 | char *auth_type, char *arg, char **username) |
67 | { | 92 | { |
68 | char *input = NULL; | 93 | char *input = NULL; |
69 | char output[512]; | 94 | char *output; |
70 | size_t output_len; | 95 | size_t output_len; |
71 | char *s; | 96 | char *s; |
72 | int rc; | 97 | int rc; |
... | @@ -84,22 +109,33 @@ auth_gsasl (struct imap4d_command *command, | ... | @@ -84,22 +109,33 @@ auth_gsasl (struct imap4d_command *command, |
84 | 109 | ||
85 | gsasl_server_application_data_set (sess_ctx, username); | 110 | gsasl_server_application_data_set (sess_ctx, username); |
86 | 111 | ||
112 | output_len = AUTHBUFSIZE; | ||
113 | output = malloc (output_len); | ||
114 | if (!output) | ||
115 | imap4d_bye (ERR_NO_MEM); | ||
116 | |||
87 | output[0] = '\0'; | 117 | output[0] = '\0'; |
88 | output_len = sizeof (output); | ||
89 | 118 | ||
90 | while ((rc = gsasl_server_step_base64 (sess_ctx, input, output, output_len)) | 119 | while ((rc = auth_step_base64 (sess_ctx, input, &output, &output_len)) |
91 | == GSASL_NEEDS_MORE) | 120 | == GSASL_NEEDS_MORE) |
92 | { | 121 | { |
93 | util_send ("+ %s\r\n", output); | 122 | util_send ("+ %s\r\n", output); |
94 | input = imap4d_readline_ex (); | 123 | input = imap4d_readline_ex (); |
95 | } | 124 | } |
96 | 125 | ||
97 | if (rc != GSASL_OK) | 126 | if (rc != GSASL_OK) |
98 | { | 127 | { |
99 | syslog (LOG_NOTICE, _("GSASL error: %s"), gsasl_strerror (rc)); | 128 | syslog (LOG_NOTICE, _("GSASL error: %s"), gsasl_strerror (rc)); |
129 | free (output); | ||
100 | return RESP_NO; | 130 | return RESP_NO; |
101 | } | 131 | } |
102 | 132 | ||
133 | /* Some SASL mechanisms output data when GSASL_OK is returned */ | ||
134 | if (output[0]) | ||
135 | util_send ("+ %s\r\n", output); | ||
136 | |||
137 | free (output); | ||
138 | |||
103 | if (*username == NULL) | 139 | if (*username == NULL) |
104 | { | 140 | { |
105 | syslog (LOG_NOTICE, _("GSASL %s: cannot get username"), auth_type); | 141 | syslog (LOG_NOTICE, _("GSASL %s: cannot get username"), auth_type); | ... | ... |
-
Please register or sign in to post a comment