/* * checkpop.c * * Supposedly generic code to check user authentication credentials through * POP3 authentication. Designed as an authentication mechanism for use with * PHP SpamAssasin MySQL (http://www.peregrinehw.com/downloads/). * * Tested to work fine with GNU POP3d, should work fine with other popper * daemons, if it dosnt please send a bug report. * * Bug reports to: tom+cpop@rooted.net * */ #include #include #include #include #include #define PORT 110 #define ERR -1 #define POK 0 int main(int argc, char **argv) { int sockfd; int pwrf=0; int i=0,c=0; char popbuf[80]; char tmpbuf[2]; char quit[20]; char *user, *pass; struct sockaddr_in server; struct hostent *he; if(argc < 3) { return(ERR); } if ((user = (char *) malloc(20)) == NULL) { printf("malloc failed\n"); exit(ERR); } if ((pass = (char *) malloc(20)) == NULL) { printf("malloc failed\n"); exit(ERR); } sockfd = socket(AF_INET, SOCK_STREAM, 0); if(sockfd < 0) perror("Error opening socket"); he = gethostbyname(argv[1]); if(he == NULL) perror("gethostbyname() failed"); memset(&server, 0x00, sizeof(struct sockaddr_in)); memcpy(&server.sin_addr, he->h_addr_list[0], he->h_length); server.sin_family = AF_INET; server.sin_port = htons(110); if(connect(sockfd, (struct sockaddr *) &server, sizeof(server)) == -1) { printf("Error connecting"); exit(ERR); } memset(user, 0x00, 20); memset(pass, 0x00, 20); memset(quit, 0x00, 20); memset(popbuf, 0x00, sizeof(popbuf)); snprintf(user, 20, "USER %s\r\n", argv[2]); snprintf(pass, 20, "PASS %s\r\n", argv[3]); sprintf(quit, "QUIT\r\n"); write(sockfd, user, strlen(user)); write(sockfd, pass, strlen(pass)); while( (read(sockfd, tmpbuf, 1) ) != -1) { i++; if(tmpbuf[0] == '\x0A') { if(strstr(popbuf, "-ERR") != NULL) { if(user != NULL) free(user); if(pass != NULL) free(user); write(sockfd, quit, strlen(quit)); close(sockfd); exit(ERR); } else if(strstr(popbuf, "Password required for") != NULL) { pwrf = 1; } else if((pwrf == 1) && strstr(popbuf, "+OK") != NULL) { if(user != NULL) free(user); if(pass != NULL) free(user); write(sockfd, quit, strlen(quit)); close(sockfd); exit(POK); } i=0; memset(popbuf, 0x00, sizeof(popbuf)); } popbuf[i] = tmpbuf[0]; } if(user != NULL) free(user); if(pass != NULL) free(user); write(sockfd, quit, strlen(quit)); close(sockfd); return(ERR); }