case P_IMAP:
die("STARTTLS for IMAP not implemented yet.");
break;
+ case 0:
+ /* Don't use STARTTLS */
+ starttls_ok = 0;
+ break;
default:
die("Unknown STARTTLS protocol requested.");
}
cert_list = gnutls_certificate_get_peers( session, &cert_list_size );
today = time(NULL);
-
+
for (int i = 0; i < cert_list_size; i++) {
gnutls_x509_crt_init( &cert );
gnutls_x509_crt_import( cert, &cert_list[0], GNUTLS_X509_FMT_DER );
}
/* Clean up */
- err = gnutls_bye( session, GNUTLS_SHUT_WR );
- if (err < 0) gnutls_die(err);
- close( fd );
+
+ /* This could use some other parameter. */
+ switch (use_starttls) {
+ case P_SMTP:
+ smtp_quit(session);
+ break;
+ case P_IMAP:
+ die("IMAP not implemented yet.");
+ break;
+ default:;
+ }
+
+// err = gnutls_bye( session, GNUTLS_SHUT_WR );
+// if (err < 0) gnutls_die(err);
+// close( fd );
cleanup:
gnutls_deinit( session );
gnutls_certificate_free_credentials( xcred );
#define _XOPEN_SOURCE 500
+#include <gnutls/gnutls.h>
+
#include <unistd.h>
#include <string.h>
return ptr;
}
+/* Expect status code. This can be done better. */
+char* ssl_smtp_expect(gnutls_session_t session, char *str) {
+ char buffer[BUFFER_SIZE];
+ int len = strlen(str);
+ int bytes = gnutls_record_recv(session, buffer, BUFFER_SIZE);
+ if (bytes < len) goto fail;
+ if (!strncmp(buffer,str,len)) {
+ return NULL;
+ }
+
+ fail:;
+ return strdup(buffer);
+}
+
/* Send EHLO and check for STARTTLS extension. */
int smtp_ehlo(int fd) {
return 0;
}
return 0;
}
+
+/* Ugly, sending could fail and other horrible things may happen. */
+int smtp_quit(gnutls_session_t session) {
+ char buffer[] = "QUIT\n";
+ int sent = GNUTLS_E_AGAIN;
+ sent = gnutls_record_send(session, buffer, sizeof(buffer));
+
+ ssl_smtp_expect(session, "221 ");
+
+ /* TODO: Better (read: some) error handling. */
+ return 0;
+}
int smtp_ehlo(int fd);
char* smtp_expect(int fd, char *str);
int smtp_starttls(int fd);
+int smtp_quit(gnutls_session_t session);
#endif