+ if (tls) {
+ if (!capability_set("STARTTLS")) {
+ fprintf(stderr, "Requested STARTTLS with -tls, but IMAP server "
+ "has no support for STARTTLS\n");
+ goto finish;
+ }
+ if (send_imap_command(nsc, false, &errstr, "STARTTLS") != OK) {
+ fprintf(stderr, "Unable to issue STARTTLS: %s\n", errstr);
+ goto finish;
+ }
+
+ if (get_imap_response(nsc, NULL, NULL, NULL, 1, &errstr) != OK) {
+ fprintf(stderr, "STARTTLS failed: %s\n", errstr);
+ goto finish;
+ }
+ if (netsec_negotiate_tls(nsc, &errstr) != OK) {
+ die("%s", errstr);
+ }
+ }
+
+ if (sasl) {
+ if (netsec_negotiate_sasl(nsc, saslmechs, &errstr) != OK) {
+ fprintf(stderr, "SASL negotiation failed: %s\n", errstr);
+ goto finish;
+ }
+ /*
+ * Sigh. If we negotiated a SSF AND we got a capability response
+ * as part of the AUTHENTICATE OK message, we can't actually trust
+ * it because it's not protected at that point. So discard the
+ * capability list and we will generate a fresh CAPABILITY command
+ * later.
+ */
+ if (netsec_get_sasl_ssf(nsc) > 0) {
+ clear_capability();
+ }
+ } else {
+ if (capability_set("LOGINDISABLED")) {
+ fprintf(stderr, "User did not request SASL, but LOGIN "
+ "is disabled\n");
+ goto finish;
+ }
+ }
+
+ if (!have_capability()) {
+ char *capstring;
+
+ if (send_imap_command(nsc, false, &errstr, "CAPABILITY") != OK) {
+ fprintf(stderr, "Unable to send CAPABILITY command: %s\n", errstr);
+ goto finish;
+ }
+
+ if (get_imap_response(nsc, "CAPABILITY", &capstring, NULL, 1,
+ &errstr) != OK) {
+ fprintf(stderr, "Cannot get CAPABILITY response: %s\n", errstr);
+ goto finish;
+ }
+
+ if (! capstring) {
+ fprintf(stderr, "No CAPABILITY response seen\n");
+ goto finish;
+ }
+
+ parse_capability(capstring, strlen(capstring));
+ free(capstring);
+ }
+
+ if (timestamp) {
+ ts_report(&tv_connect, "Authentication time");
+ gettimeofday(&tv_auth, NULL);
+ }
+
+ while (msgqueue_head != NULL) {
+ imsg = msgqueue_head;
+
+ if (send_imap_command(nsc, imsg->queue, &errstr, "%s",
+ imsg->command) != OK) {
+ fprintf(stderr, "Cannot send command \"%s\": %s\n", imsg->command,
+ errstr);
+ free(errstr);
+ goto finish;
+ }
+
+ if (! imsg->queue) {
+ if (get_imap_response(nsc, NULL, NULL, NULL, 0, &errstr) != OK) {
+ fprintf(stderr, "Unable to get response for command "
+ "\"%s\": %s\n", imsg->command, errstr);
+ goto finish;
+ }
+ }
+
+ msgqueue_head = imsg->next;
+
+ free(imsg->command);
+ free(imsg);
+ }
+
+ if (timestamp)
+ ts_report(&tv_auth, "Total command execution time");
+
+ send_imap_command(nsc, 0, NULL, "LOGOUT");
+ get_imap_response(nsc, NULL, NULL, NULL, 0, NULL);