Skip to content

Commit 0b3773e

Browse files
imap: Integrated new capability list API
Updated imap to use the new capability list API from lib-imap which will allow for post-login imap capabilities to be displayed conditionally. This ensures functionality of client_add_capability() does not change, and it introduces a new imap function client_get_capability() which is now used everywhere that client->capability_string was previously used.
1 parent ee5be57 commit 0b3773e

File tree

4 files changed

+51
-14
lines changed

4 files changed

+51
-14
lines changed

src/imap/cmd-capability.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
bool cmd_capability(struct client_command_context *cmd)
88
{
99
client_send_line(cmd->client, t_strconcat(
10-
"* CAPABILITY ", str_c(cmd->client->capability_string), NULL));
10+
"* CAPABILITY ", client_get_capability(cmd->client), NULL));
1111

1212
client_send_tagline(cmd, "OK Capability completed.");
1313
return TRUE;

src/imap/imap-client.c

Lines changed: 43 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
#include "imap-search.h"
2525
#include "imap-notify.h"
2626
#include "imap-commands.h"
27+
#include "imap-capability-list.h"
2728

2829
#include <unistd.h>
2930

@@ -156,17 +157,22 @@ struct client *client_create(int fd_in, int fd_out, const char *session_id,
156157
&client->output);
157158
}
158159

159-
client->capability_string =
160-
str_new(client->pool, sizeof(CAPABILITY_STRING)+64);
160+
/* create our capability list */
161+
client->capability_list = imap_capability_list_create(NULL);
161162

162163
if (*set->imap_capability == '\0')
163-
str_append(client->capability_string, CAPABILITY_STRING);
164+
imap_capability_list_append_string(client->capability_list,
165+
CAPABILITY_STRING);
164166
else if (*set->imap_capability != '+') {
165-
str_append(client->capability_string, set->imap_capability);
167+
imap_capability_list_append_string(client->capability_list,
168+
set->imap_capability);
166169
} else {
167-
str_append(client->capability_string, CAPABILITY_STRING);
168-
str_append_c(client->capability_string, ' ');
169-
str_append(client->capability_string, set->imap_capability + 1);
170+
/* add the capability banner string to the cap list */
171+
imap_capability_list_append_string(client->capability_list,
172+
CAPABILITY_STRING);
173+
/* add everything after the plus to our cap list */
174+
imap_capability_list_append_string(client->capability_list,
175+
client->set->imap_capability + 1);
170176
}
171177
if (client->set->imap_literal_minus)
172178
client_add_capability(client, "LITERAL-");
@@ -552,8 +558,36 @@ void client_add_capability(struct client *client, const char *capability)
552558
/* explicit capability - don't change it */
553559
return;
554560
}
555-
str_append_c(client->capability_string, ' ');
556-
str_append(client->capability_string, capability);
561+
562+
/* add it to our capability list as CAP_ALWAYS */
563+
imap_capability_list_add(client->capability_list,
564+
capability, IMAP_CAP_VISIBILITY_ALWAYS);
565+
}
566+
567+
const char *client_get_capability(struct client *client)
568+
{
569+
string_t *cap_str = t_str_new(256);
570+
571+
/* imap is postauth by definition */
572+
uint32_t flags = IMAP_CAP_VISIBILITY_POSTAUTH;
573+
574+
/* is the client secured by means of ssl? */
575+
if (client->ssl_secured)
576+
flags |= IMAP_CAP_VISIBILITY_TLS_ACTIVE;
577+
else
578+
flags |= IMAP_CAP_VISIBILITY_TLS_INACTIVE;
579+
580+
/* Are we secured? (localhost? tls? etc) */
581+
if (client->secured)
582+
flags |= IMAP_CAP_VISIBILITY_SECURE;
583+
else
584+
flags |= IMAP_CAP_VISIBILITY_INSECURE;
585+
586+
/* build capability string based on IMAP_CAP_VISIBILITY_ flags */
587+
imap_capability_list_get_capability(client->capability_list,
588+
cap_str, flags);
589+
590+
return str_c(cap_str);
557591
}
558592

559593
void client_send_line(struct client *client, const char *data)

src/imap/imap-client.h

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -158,7 +158,7 @@ struct client {
158158
struct mail_storage_service_user *service_user;
159159
const struct imap_settings *set;
160160
const struct smtp_submit_settings *smtp_set;
161-
string_t *capability_string;
161+
struct imap_capability_list *capability_list;
162162
const char *disconnect_reason;
163163

164164
struct mail_user *user;
@@ -271,6 +271,9 @@ void client_disconnect_with_error(struct client *client, const char *msg);
271271
has an explicit capability, nothing is changed. */
272272
void client_add_capability(struct client *client, const char *capability);
273273

274+
/* Generate the string of capabilities from the client */
275+
const char *client_get_capability(struct client *client);
276+
274277
/* Send a line of data to client. */
275278
void client_send_line(struct client *client, const char *data);
276279
/* Send a line of data to client. Returns 1 if ok, 0 if buffer is getting full,

src/imap/main.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -193,19 +193,19 @@ client_add_input_capability(struct client *client, const unsigned char *client_i
193193
if (input.tag == NULL) {
194194
client_send_line(client, t_strconcat(
195195
"* PREAUTH [CAPABILITY ",
196-
str_c(client->capability_string), "] "
196+
client_get_capability(client), "] "
197197
"Logged in as ", client->user->username, NULL));
198198
} else if (input.send_untagged_capability) {
199199
/* client doesn't seem to understand tagged capabilities. send
200200
untagged instead and hope that it works. */
201201
client_send_line(client, t_strconcat("* CAPABILITY ",
202-
str_c(client->capability_string), NULL));
202+
client_get_capability(client), NULL));
203203
client_send_line(client,
204204
t_strconcat(input.tag, " OK Logged in", NULL));
205205
} else {
206206
client_send_line(client, t_strconcat(
207207
input.tag, " OK [CAPABILITY ",
208-
str_c(client->capability_string), "] Logged in", NULL));
208+
client_get_capability(client), "] Logged in", NULL));
209209
}
210210
o_stream_uncork(output);
211211
o_stream_unref(&output);

0 commit comments

Comments
 (0)