Skip to content

Commit 323714d

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 4ccde42 commit 323714d

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
@@ -25,6 +25,7 @@
2525
#include "imap-notify.h"
2626
#include "imap-commands.h"
2727
#include "imap-feature.h"
28+
#include "imap-capability-list.h"
2829

2930
#include <unistd.h>
3031

@@ -161,17 +162,22 @@ struct client *client_create(int fd_in, int fd_out, const char *session_id,
161162
&client->output);
162163
}
163164

164-
client->capability_string =
165-
str_new(client->pool, sizeof(CAPABILITY_STRING)+64);
165+
/* create our capability list */
166+
client->capability_list = imap_capability_list_create(NULL);
166167

167168
if (*set->imap_capability == '\0')
168-
str_append(client->capability_string, CAPABILITY_STRING);
169+
imap_capability_list_append_string(client->capability_list,
170+
CAPABILITY_STRING);
169171
else if (*set->imap_capability != '+') {
170-
str_append(client->capability_string, set->imap_capability);
172+
imap_capability_list_append_string(client->capability_list,
173+
set->imap_capability);
171174
} else {
172-
str_append(client->capability_string, CAPABILITY_STRING);
173-
str_append_c(client->capability_string, ' ');
174-
str_append(client->capability_string, set->imap_capability + 1);
175+
/* add the capability banner string to the cap list */
176+
imap_capability_list_append_string(client->capability_list,
177+
CAPABILITY_STRING);
178+
/* add everything after the plus to our cap list */
179+
imap_capability_list_append_string(client->capability_list,
180+
client->set->imap_capability + 1);
175181
}
176182
if (client->set->imap_literal_minus)
177183
client_add_capability(client, "LITERAL-");
@@ -565,8 +571,36 @@ void client_add_capability(struct client *client, const char *capability)
565571
/* explicit capability - don't change it */
566572
return;
567573
}
568-
str_append_c(client->capability_string, ' ');
569-
str_append(client->capability_string, capability);
574+
575+
/* add it to our capability list as CAP_ALWAYS */
576+
imap_capability_list_add(client->capability_list,
577+
capability, IMAP_CAP_VISIBILITY_ALWAYS);
578+
}
579+
580+
const char *client_get_capability(struct client *client)
581+
{
582+
string_t *cap_str = t_str_new(256);
583+
584+
/* imap is postauth by definition */
585+
enum imap_capability_visibility visibility = IMAP_CAP_VISIBILITY_POSTAUTH;
586+
587+
/* is the client secured by means of ssl? */
588+
if (client->ssl_secured)
589+
visibility |= IMAP_CAP_VISIBILITY_TLS_ACTIVE;
590+
else
591+
visibility |= IMAP_CAP_VISIBILITY_TLS_INACTIVE;
592+
593+
/* Are we secured? (localhost? tls? etc) */
594+
if (client->secured)
595+
visibility |= IMAP_CAP_VISIBILITY_SECURE;
596+
else
597+
visibility |= IMAP_CAP_VISIBILITY_INSECURE;
598+
599+
/* build capability string based on IMAP_CAP_VISIBILITY_ flags */
600+
imap_capability_list_get_capability(client->capability_list,
601+
cap_str, visibility);
602+
603+
return str_c(cap_str);
570604
}
571605

572606
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
@@ -166,7 +166,7 @@ struct client {
166166
struct mail_storage_service_user *service_user;
167167
const struct imap_settings *set;
168168
const struct smtp_submit_settings *smtp_set;
169-
string_t *capability_string;
169+
struct imap_capability_list *capability_list;
170170
const char *disconnect_reason;
171171

172172
struct mail_user *user;
@@ -283,6 +283,9 @@ void client_disconnect_with_error(struct client *client,
283283
has an explicit capability, nothing is changed. */
284284
void client_add_capability(struct client *client, const char *capability);
285285

286+
/* Generate the string of capabilities from the client */
287+
const char *client_get_capability(struct client *client);
288+
286289
/* Send a line of data to client. */
287290
void client_send_line(struct client *client, const char *data);
288291
/* 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
@@ -194,19 +194,19 @@ client_add_input_capability(struct client *client, const unsigned char *client_i
194194
if (input.tag == NULL) {
195195
client_send_line(client, t_strconcat(
196196
"* PREAUTH [CAPABILITY ",
197-
str_c(client->capability_string), "] "
197+
client_get_capability(client), "] "
198198
"Logged in as ", client->user->username, NULL));
199199
} else if (input.send_untagged_capability) {
200200
/* client doesn't seem to understand tagged capabilities. send
201201
untagged instead and hope that it works. */
202202
client_send_line(client, t_strconcat("* CAPABILITY ",
203-
str_c(client->capability_string), NULL));
203+
client_get_capability(client), NULL));
204204
client_send_line(client,
205205
t_strconcat(input.tag, " OK Logged in", NULL));
206206
} else {
207207
client_send_line(client, t_strconcat(
208208
input.tag, " OK [CAPABILITY ",
209-
str_c(client->capability_string), "] Logged in", NULL));
209+
client_get_capability(client), "] Logged in", NULL));
210210
}
211211
o_stream_uncork(output);
212212
o_stream_unref(&output);

0 commit comments

Comments
 (0)