rendered paste body#include <sys/syslog.h>#include <stdio.h>#include <sys/types.h>#include <sys/socket.h>#include <netinet/in.h>#include <netdb.h>#define BUF_SIZE 1024#define MAX_PARAMS 4#define TRUE_RESULT 0x01#define FALSE_RESULT 0x00int pop3_check(char *user, char *domain, char *userpass ) {char buffer[2560];char *port="pop3", hostname="mars.neolocation.net", *getstr , username[1000] ; // *usernameint i, hnp;i=hnp=0;/* connecting to host */ struct addrinfo hints, *res, *res0; int error; int s; const char *cause = NULL; memset(&hints, 0, sizeof(hints)); hints.ai_family = PF_UNSPEC; hints.ai_socktype = SOCK_STREAM; error = getaddrinfo(hostname, port, &hints, &res0); if (error) { errx(1, "%s", gai_strerror(error)); /*NOTREACHED*/ } s = -1; for (res = res0; res; res = res->ai_next) { s = socket(res->ai_family, res->ai_socktype, res->ai_protocol); if (s < 0) { cause = "socket"; continue; } if (connect(s, res->ai_addr, res->ai_addrlen) < 0) { cause = "connect"; close(s); s = -1; continue; } break; /* okay we got one */ } if (s < 0) { err(1, "%s", cause); /*NOTREACHED*/ } freeaddrinfo(res0);/* end connecting to host */ fd_set fds; struct timeval timeout; timeout.tv_sec = 50; timeout.tv_usec = 0; memset(buffer, 0, sizeof(buffer)); FD_ZERO(&fds); FD_SET(s, &fds); select(FD_SETSIZE, &fds, NULL, NULL, &timeout); read(s,buffer,sizeof(buffer)); //read "OK" //printf("got response <- %s\n",buffer); memset(buffer, 0, sizeof(buffer)); FD_ZERO(&fds); FD_SET(s, &fds); select(FD_SETSIZE, NULL, &fds, NULL, &timeout); strcpy(buffer,"user "); strcpy(buffer+strlen(buffer),user); strcpy(buffer+strlen(buffer),"@"); strcpy(buffer+strlen(buffer),domain); strcpy(buffer+strlen(buffer),"\n"); //printf("say -> %s\n",buffer); syslog( LOG_ERR, "%s", buffer); write(s,buffer,strlen(buffer)); memset(buffer, 0, sizeof(buffer)); FD_ZERO(&fds); FD_SET(s, &fds); select(FD_SETSIZE, &fds, NULL, NULL, &timeout); read(s,buffer,sizeof(buffer)); //read "OK" //printf("got response <- %s\n",buffer); syslog( LOG_ERR, "%s", buffer); memset(buffer, 0, sizeof(buffer)); FD_ZERO(&fds); FD_SET(s, &fds); select(FD_SETSIZE, NULL, &fds, NULL, &timeout); strcpy(buffer,"pass "); strcpy(buffer+strlen(buffer),userpass); strcpy(buffer+strlen(buffer),"\n"); //printf("say -> %s\n",buffer); syslog( LOG_ERR, "%s", buffer); write(s,buffer,strlen(buffer)); memset(buffer, 0, sizeof(buffer)); FD_ZERO(&fds); FD_SET(s, &fds); select(FD_SETSIZE, &fds, NULL, NULL, &timeout); read(s,buffer,sizeof(buffer)); //read "OK" //printf("got response <- %s\n",buffer); syslog( LOG_ERR, "%s", buffer); if ( strstr(buffer,"+OK")!=NULL ) { return 1; //ok } else { return 0; //fail }}int main() { char buf[BUF_SIZE + 1]; // Allow for string termination char c; char* param[MAX_PARAMS]; param[0] = &buf[0]; // this won't change... short len; int i,j; int result; openlog( "ejabberd", LOG_NDELAY, LOG_AUTH ); syslog( LOG_INFO, "Starting ejabberd check_pop3" ); while( 1 ) { // read first two bytes from stdin // convert bytes to integer len i=0; while( i<2 ) { c = getchar(); if( c == EOF ) return 0; buf[i++] = c; } len = buf[0]*256 + buf[1]; if( len == 0 ) { syslog( LOG_WARNING, "Packet length is zero" ); // try again continue; } else if( len < 0 ) { syslog( LOG_ERR, "Negative packet length; exiting" ); return 1; } else if( len > BUF_SIZE ) { syslog( LOG_ERR, "Packet length of %d larger than buffer of size %d", len, BUF_SIZE ); return 1; } //syslog( LOG_DEBUG, "packet length %d", len ); // read packet of len bytes from stdin to buffer // note: packet is on the form [auth|setpass|isuser]:<user>:<domain>:<password> // example: 36auth:christoffer:jabberwocky.se:test i=0; j=0; while( i<len & j<MAX_PARAMS ) { c = getchar(); if( c == EOF ) return 0; // split packet on ':' if( c == ':' ) { // terminate string buf[i] = '\0'; // store index of next string // NB if i==BUF_SIZE-1 this will point to the last positon in the array // since the length of the array == BUF_SIZE+1 param[++j]=&buf[i]+1; } else { // store character buf[i]=c; } i++; } // terminate the last parameter buf[i] = '\0'; // syslog( LOG_INFO, "op: %s, user: %s, domain: %s, pass: %s", \ param[0], param[1], param[2], param[3] ); if( strcmp( param[0], "auth" )==0 ) { if( j!=3 ) { syslog( LOG_ERR, "Expected exactly four parameters, found %d", j+1 ); return 1; } result = pop3_check(param[1],param[2], param[3]); syslog( LOG_DEBUG, \ "Authentication for user '%s@%s' %s", \ param[1], \ param[2], \ result ? "was successfull" : "failed" ); } else if( strcmp( param[0], "setpass" )==0 ) { // TODO: Test setpass operation if( j!=3 ) { syslog( LOG_ERR, "Expected exactly four parameters, found %d", j+1 ); return 1; } result = NULL; syslog( LOG_INFO, "The password for user '%s@%si' %s changed", \ param[1], param[2], result == 0 ? "was" : "could not be" ); } else if( strcmp( param[0], "isuser" )==0 ) { // TODO: Test isuser operation // FIXME: Find out if the password is sent or not, i.e. if we get // three or four parameters. if( j<2 ) { syslog( LOG_ERR, "Expected at least two parameters, found %d", j+1 ); return 1; } // The theory is: if we get a passwd struct back, the user exists... result = NULL; } else { // if we don't know what to do, the result is a failure result = 0; // log warning syslog( LOG_ERR, "Unknown operation '%s'", param[0] ); } // write back the result length (2 bytes) //fputs( "\x00\x02", stdout ); putchar( 0x00 ); putchar( 0x02 ); // write back the result putchar( 0x00 ); putchar( result ? TRUE_RESULT : FALSE_RESULT ); fflush( stdout ); // syslog( LOG_DEBUG, "Returned result" ); } return 0;}