/********
Get configuration file name
*/
+#ifdef DEBUG
syslog(LOG_DEBUG, "pam_smtpauth: pam_sm_authenticate()");
+#endif
if(argc == 0) {
if((fd = open(SMTPAUTH_CONF, O_RDONLY)) != -1) {
strcpy(configfile, SMTPAUTH_CONF);
syslog(LOG_ERR, "pam_smtpauth: no user specified.");
return PAM_USER_UNKNOWN;
}
+#ifdef DEBUG
syslog(LOG_DEBUG, "pam_smtpauth: username=%s", username);
+#endif
/********
Get password
*/
if(password != NULL) {
+#ifdef DEBUG
syslog(LOG_DEBUG, "pam_smtpauth: password is not NULL.");
+#endif
pam_set_item(pamh, PAM_AUTHTOK, (const void**)&password);
}
result = pam_get_item(pamh, PAM_AUTHTOK, (const void **)&password);
timeout = atoi(timeout_buf);
}
global.timeout = timeout;
+#ifdef DEBUG
syslog(LOG_DEBUG, "pam_smtpauth: timeout: %d",timeout);
+#endif
for(cnt=0;;cnt++) {
result = smtp_connect(cnt);
+#ifdef DEBUG
syslog(LOG_DEBUG, "pam_smtpauth: smtp_connect cnt=%d result=%d", cnt, result);
+#endif
if(result == SA_NO_SERVER_LEFT) {
+#ifdef DEBUG
syslog(LOG_DEBUG, "pam_smtpauth: auth service cannot retrieve information.");
+#endif
password = NULL;
global.password = NULL;
return PAM_AUTHINFO_UNAVAIL;
char *smtp_server;
char *buffer;
- syslog(LOG_WARNING, "pam_smtpauth: smtp_connect num=%d", num);
+#ifdef DEBUG
+ syslog(LOG_DEBUG, "pam_smtpauth: smtp_connect num=%d", num);
+#endif
strcpy(param, "SMTPServer_");
sprintf(tnum, "%d", num);
strcat(param, tnum);
smtp_server = get_config(configfile, param);
- syslog(LOG_WARNING, "pam_smtpauth: smtp_server=%s", smtp_server);
+#ifdef DEBUG
+ syslog(LOG_DEBUG, "pam_smtpauth: smtp_server=%s", smtp_server);
+#endif
if(smtp_server == NULL) {
return SA_NO_SERVER_LEFT;
buffer = strtok(NULL, ":");
global.port = atoi(buffer);
}
+#ifdef DEBUG
syslog(LOG_DEBUG, "pam_smtpauth: global.host=%s", global.host);
syslog(LOG_DEBUG, "pam_smtpauth: global.port=%d", global.port);
syslog(LOG_DEBUG, "pam_smtpauth: global.username=%s", global.username);
syslog(LOG_DEBUG, "pam_smtpauth: global.password=%s", global.password);
+#endif
smtp = (smtp_t *)smtp_auth(&global);
+#ifdef DEBUG
syslog(LOG_DEBUG, "pam_smtpauth: smtp->error=%d", smtp->error);
+#endif
//sleep(3);
if(smtp == 0) {
if(result == PAM_SUCCESS) {
result = conv->conv(nargs, (const struct pam_message **)msg, resp, conv->appdata_ptr);
if((result != PAM_SUCCESS) && (result != PAM_CONV_AGAIN)) {
+#ifdef DEBUG
syslog(LOG_DEBUG, "pam_smtpauth: conversation failure [%s]", pam_strerror(pamh, result));
+#endif
}
}
else {
he = gethostbyname(cfg->host);
if(!he) {
smtp->error = 1;
- strcpy(msgbuf, "Error Resolving Host ");
+ strcpy(msgbuf, "Error: resolving hostname ");
strcat(msgbuf, cfg->host);
smtp->error_message = malloc(strlen(msgbuf) + 1);
strcpy(smtp->error_message, msgbuf);
if(he->h_addrtype == AF_INET) {
memset((char*)&taddr, 0, sizeof(taddr));
memcpy((char*)&taddr.sin_addr, he->h_addr_list[n], he->h_length);
+#ifdef DEBUG
syslog(LOG_DEBUG, "pam_smtpauth(smtpauth): my ip: %s",
inet_ntoa(((struct sockaddr_in *)&ifreq.ifr_addr)->sin_addr));
syslog(LOG_DEBUG, "pam_smtpauth(smtpauth): smtp ip: %s",
inet_ntoa(taddr.sin_addr));
+#endif
if(((struct sockaddr_in *)&ifreq.ifr_addr)->sin_addr.s_addr == taddr.sin_addr.s_addr) {
smtp->error = 1;
strcpy(msgbuf, "Error: this host is specified. ");
s = socket(PF_INET, SOCK_STREAM, 0);
if(connect (s, (struct sockaddr *) &addr, sizeof (addr))) {
smtp->error = 1;
- strcpy(msgbuf, "Error Connecting to ");
+ strcpy(msgbuf, "Error: connecting to ");
strcat(msgbuf, inet_ntoa(addr.sin_addr));
smtp->error_message = malloc(strlen(msgbuf) + 1);
strcpy(smtp->error_message, msgbuf);
rc = read(s, rbuf, sizeof(rbuf));
alarm(0);
if (rc == -1) {
+#ifdef DEBUG
syslog(LOG_DEBUG, "pam_smtpauth(smtpauth): read (banner): %m");
+#endif
smtp->error = 1;
strcpy(msgbuf, RESP_SYNCERROR);
smtp->error_message = malloc(strlen(msgbuf) + 1);
}
if(strncmp(rbuf, "220 ", sizeof("220 ")-1)) {
+#ifdef DEBUG
syslog(LOG_DEBUG, "pam_smtpauth(smtpauth): unexpected response during initial handshake: %s", rbuf);
+#endif
smtp->error = 1;
strcpy(msgbuf, RESP_UNEXPECTED);
smtp->error_message = malloc(strlen(msgbuf) + 1);
iov[2].iov_base = "\r\n";
iov[2].iov_len = sizeof("\r\n") - 1;
+#ifdef DEBUG
syslog(LOG_DEBUG, "pam_smtpauth(smtpauth): sending %s%s", EHLO_CMD, myhostname);
+#endif
alarm(cfg->timeout);
rc = retry_writev(s, iov, 3);
memset(iov, 0, sizeof(iov));
alarm(0);
if(rc == -1) {
+#ifdef DEBUG
syslog(LOG_DEBUG, "pam_smtpauth(smtpauth): writev: %m");
+#endif
smtp->error = 1;
strcpy(msgbuf, RESP_IERROR);
smtp->error_message = malloc(strlen(msgbuf) + 1);
rc = read(s, rbuf, sizeof(rbuf));
alarm(0);
if(rc == -1) {
+#ifdef DEBUG
syslog(LOG_DEBUG, "pam_smtpauth(smtpauth): read (response): %m");
+#endif
smtp->error = 1;
strcpy(msgbuf, RESP_IERROR);
smtp->error_message = malloc(strlen(msgbuf) + 1);
}
if (avail_auth_type == 0) {
+#ifdef DEBUG
syslog(LOG_DEBUG, "pam_smtpauth(smtpauth): smtp authentication is not implemented: %s", rbuf);
+#endif
smtp->error = 1;
strcpy(msgbuf, RESP_UNEXPECTED);
smtp->error_message = malloc(strlen(msgbuf) + 1);
strcpy(smtp->error_message, msgbuf);
goto bail;
}
+#ifdef DEBUG
syslog(LOG_DEBUG, "pam_smtpauth(smtpauth): auth_type: %d", avail_auth_type);
+#endif
/* build the AUTH command */
if (avail_auth_type & AUTH_CRAM_MD5) {
auth = auth_plain(s,&global);
}
else {
+#ifdef DEBUG
syslog(LOG_DEBUG, "pam_smtpauth(smtpauth): smtp authentication is not implemented: %s", rbuf);
+#endif
smtp->error = 1;
strcpy(msgbuf, RESP_UNEXPECTED);
smtp->error_message = malloc(strlen(msgbuf) + 1);
goto bail;
}
+#ifdef DEBUG
syslog(LOG_DEBUG, "pam_smtpauth(smtpauth) auth: [%d]", auth);
+#endif
if(auth == 0) {
+#ifdef DEBUG
syslog(LOG_DEBUG, "pam_smtpauth(smtpauth) rejected: [%s]", global.username);
+#endif
smtp->error = 2;
strcpy(msgbuf, RESP_CREDERROR);
smtp->error_message = malloc(strlen(msgbuf) + 1);
iov[1].iov_base = "\r\n";
iov[1].iov_len = sizeof("\r\n") - 1;
+#ifdef DEBUG
syslog(LOG_DEBUG, "pam_smtpauth(smtpauth): sending %s", QUIT_CMD);
+#endif
alarm(cfg->timeout);
rc = retry_writev(s, iov, 2);
memset(iov, 0, sizeof(iov));
alarm(0);
if(rc == -1) {
+#ifdef DEBUG
syslog(LOG_DEBUG, "pam_smtpauth(smtpauth): quit writev: %m");
+#endif
}
(void)close(s);
}
char rbuf[RESP_LEN];
char buf[RESP_LEN];
+#ifdef DEBUG
syslog(LOG_DEBUG, "pam_smtpauth(smtpauth): AUTH CRAM-MD5");
+#endif
iov[0].iov_base = AUTH_CMD;
iov[0].iov_len = sizeof(AUTH_CMD) - 1;
iov[1].iov_base = "CRAM-MD5";
iov[2].iov_base = "\r\n";
iov[2].iov_len = sizeof("\r\n") - 1;
+#ifdef DEBUG
syslog(LOG_DEBUG, "pam_smtpauth(smtpauth): sending %s%s", AUTH_CMD, "CRAM-MD5");
+#endif
alarm(cfg->timeout);
rc = retry_writev(s, iov, 3);
memset(iov, 0, sizeof(iov));
alarm(0);
if(rc == -1) {
+#ifdef DEBUG
syslog(LOG_DEBUG, "pam_smtpauth(smtpauth): cram-md5 writev: %m");
+#endif
return AUTH_NG;
}
rc = read(s, rbuf, sizeof(rbuf));
alarm(0);
if(rc == -1) {
+#ifdef DEBUG
syslog(LOG_DEBUG, "pam_smtpauth(smtpauth): read (response): %m");
+#endif
return AUTH_NG;
}
+#ifdef DEBUG
syslog(LOG_DEBUG, "pam_smtpauth(smtpauth): read (response): %s",rbuf);
+#endif
if(strncmp(rbuf, "334 ", sizeof("334 ")-1) == 0) {
char *response;
char *response64;
challenge = malloc(strlen(rbuf + 4) + 1);
challengelen = base64_decode(challenge, rbuf + 4, -1);
challenge[challengelen] = '\0';
+#ifdef DEBUG
syslog(LOG_DEBUG, "pam_smtpauth(smtpauth): challenge=%s", challenge);
+#endif
snprintf(buf, sizeof(buf), "%s", cfg->password);
md5_hex_hmac(hexdigest, challenge, challengelen, buf, strlen(cfg->password));
iov[1].iov_base = "\r\n";
iov[1].iov_len = sizeof("\r\n") - 1;
+#ifdef DEBUG
syslog(LOG_DEBUG, "pam_smtpauth(smtpauth): sending %s", response64);
+#endif
alarm(cfg->timeout);
rc = retry_writev(s, iov, 2);
memset(iov, 0, sizeof(iov));
alarm(0);
if(rc == -1) {
+#ifdef DEBUG
syslog(LOG_DEBUG, "pam_smtpauth(smtpauth): cram-md5 writev: %m");
+#endif
return AUTH_NG;
}
rc = read(s, rbuf, sizeof(rbuf));
alarm(0);
if(rc == -1) {
+#ifdef DEBUG
syslog(LOG_DEBUG, "pam_smtpauth(smtpauth): read (response): %m");
+#endif
return AUTH_NG;
}
+#ifdef DEBUG
syslog(LOG_DEBUG, "pam_smtpauth(smtpauth): read (response): %s",rbuf);
+#endif
if(strncmp(rbuf, "235 ", sizeof("235 ")-1) != 0) {
+#ifdef DEBUG
syslog(LOG_DEBUG, "pam_smtpauth(smtpauth): auth failure.");
+#endif
return AUTH_NG;
}
free(response64);
} else {
+#ifdef DEBUG
syslog(LOG_DEBUG, "pam_smtpauth(smtpauth): it seems cram-md5 mech is not implemented.");
+#endif
return AUTH_NG;
}
return AUTH_OK;
//char buf[RESP_LEN];
char *buf;
+#ifdef DEBUG
syslog(LOG_DEBUG, "pam_smtpauth(smtpauth): AUTH LOGIN");
+#endif
iov[0].iov_base = AUTH_CMD;
iov[0].iov_len = sizeof(AUTH_CMD) - 1;
iov[1].iov_base = "LOGIN";
iov[2].iov_base = "\r\n";
iov[2].iov_len = sizeof("\r\n") - 1;
+#ifdef DEBUG
syslog(LOG_DEBUG, "pam_smtpauth(smtpauth): sending %s%s", AUTH_CMD, "LOGIN");
+#endif
alarm(cfg->timeout);
rc = retry_writev(s, iov, 3);
memset(iov, 0, sizeof(iov));
alarm(0);
if(rc == -1) {
+#ifdef DEBUG
syslog(LOG_DEBUG, "pam_smtpauth(smtpauth): login writev: %m");
+#endif
return AUTH_NG;
}
rc = read(s, rbuf, sizeof(rbuf));
alarm(0);
if(rc == -1) {
+#ifdef DEBUG
syslog(LOG_DEBUG, "pam_smtpauth(smtpauth): read (response): %m");
+#endif
return AUTH_NG;
}
+#ifdef DEBUG
syslog(LOG_DEBUG, "pam_smtpauth(smtpauth): read (response): %s",rbuf);
+#endif
if(strncmp(rbuf, "334 ", sizeof("334 ")-1) == 0) {
buf = malloc(sizeof(char)*128);
base64_encode(buf, cfg->username, strlen(cfg->username));
iov[1].iov_base = "\r\n";
iov[1].iov_len = sizeof("\r\n") - 1;
+#ifdef DEBUG
syslog(LOG_DEBUG, "pam_smtpauth(smtpauth): sending %s", buf);
+#endif
alarm(cfg->timeout);
rc = retry_writev(s, iov, 2);
memset(iov, 0, sizeof(iov));
alarm(0);
if(rc == -1) {
+#ifdef DEBUG
syslog(LOG_DEBUG, "pam_smtpauth(smtpauth): login writev: %m");
+#endif
return AUTH_NG;
}
rc = read(s, rbuf, sizeof(rbuf));
alarm(0);
if(rc == -1) {
+#ifdef DEBUG
syslog(LOG_DEBUG, "pam_smtpauth(smtpauth): read (response): %m");
+#endif
return AUTH_NG;
}
+#ifdef DEBUG
syslog(LOG_DEBUG, "pam_smtpauth(smtpauth): read (response): %s",rbuf);
+#endif
if (strncmp(rbuf, "334 ", sizeof("334 ")-1) == 0) {
buf = malloc(sizeof(char)*128);
base64_encode(buf, cfg->password, strlen(cfg->password));
iov[1].iov_base = "\r\n";
iov[1].iov_len = sizeof("\r\n") - 1;
+#ifdef DEBUG
syslog(LOG_DEBUG, "pam_smtpauth(smtpauth): sending %s", buf);
+#endif
alarm(cfg->timeout);
rc = retry_writev(s, iov, 2);
memset(iov, 0, sizeof(iov));
alarm(0);
if(rc == -1) {
+#ifdef DEBUG
syslog(LOG_WARNING, "pam_smtpauth(smtpauth): login writev: %m");
+#endif
return AUTH_NG;
}
rc = read(s, rbuf, sizeof(rbuf));
alarm(0);
if (rc == -1) {
+#ifdef DEBUG
syslog(LOG_DEBUG, "pam_smtpauth(smtpauth): read (response): %m");
+#endif
return AUTH_NG;
}
+#ifdef DEBUG
syslog(LOG_DEBUG, "pam_smtpauth(smtpauth): read (response): %s",rbuf);
+#endif
if(strncmp(rbuf, "235 ", sizeof("235 ")-1) != 0) {
+#ifdef DEBUG
syslog(LOG_DEBUG, "pam_smtpauth(smtpauth): auth failure.");
+#endif
return AUTH_NG;
}
} else {
+#ifdef DEBUG
syslog(LOG_DEBUG, "pam_smtpauth(smtpauth): it seems login mech is not implemented.");
+#endif
return AUTH_NG;
}
} else {
+#ifdef DEBUG
syslog(LOG_DEBUG, "pam_smtpauth(smtpauth): it seems login mech is not implemented.");
+#endif
return AUTH_NG;
}
return AUTH_OK;
int cnt, len;
char phrase[512];
+#ifdef DEBUG
syslog(LOG_DEBUG, "pam_smtpauth(smtpauth): AUTH PLAIN");
+#endif
sprintf(phrase,"%s^%s^%s", cfg->username, cfg->username, cfg->password);
len = strlen(phrase);
for(cnt=len-1; cnt>=0; cnt--) {
iov[3].iov_base = "\r\n";
iov[3].iov_len = sizeof("\r\n") - 1;
+#ifdef DEBUG
syslog(LOG_DEBUG, "pam_smtpauth(smtpauth): sending %s%s %s", AUTH_CMD, "PLAIN", buf);
+#endif
alarm(cfg->timeout);
rc = retry_writev(s, iov, 4);
memset(iov, 0, sizeof(iov));
free(buf);
alarm(0);
if(rc == -1) {
+#ifdef DEBUG
syslog(LOG_DEBUG, "pam_smtpauth(smtpauth): plain writev: %m");
+#endif
return AUTH_NG;
}
rc = read(s, rbuf, sizeof(rbuf));
alarm(0);
if(rc == -1) {
+#ifdef DEBUG
syslog(LOG_DEBUG, "pam_smtpauth(smtpauth): read (response): %m");
+#endif
return AUTH_NG;
}
syslog(LOG_DEBUG, "pam_smtpauth(smtpauth): read (response): %s",rbuf);
if(strncmp(rbuf, "235 ", sizeof("235 ")-1) != 0) {
+#ifdef DEBUG
syslog(LOG_DEBUG, "pam_smtpauth(smtpauth): auth failure.");
+#endif
return AUTH_NG;
}
return AUTH_OK;