/* * Copyright (c) 1996-2007, OpenFWTK Development Group * All rights reserved. See LICENSE. */ /* $Id: smftp.c,v 1.6 2007/09/10 02:49:13 arkenoi Exp $ */ #include #include #include #include #include #include #include #include "smftp.h" #include "firewall2.h" #define DIG(a) ((ln)[(a)] - '0') #define NUMSIZE 64 int strwritev(int ofd, int count, ...); int trim_eol(char *s); extern unsigned int buf_limit; /* Responses */ int ____read_smftp_response(int ifd, int *cont, char *ln, int maxsize, read_actor *reader) { int res = 0, len; *cont = 0; while((len = reader(ifd, ln, maxsize, 0))) { /* basically, ignore everything until we get a /^\d{3} / */ if(len < 4) continue; if(!isdigit((ln)[0])) continue; if(!isdigit((ln)[1])) continue; if(!isdigit((ln)[2])) continue; res = (DIG(0)*10 + DIG(1))*10 + DIG(2); break; } *cont = ((ln)[3] != ' '); trim_eol(ln); return res; } int __read_smftp_response(int ifd, char *ln, int maxsize, read_actor *reader) { int res = 0, cont; do { res = ____read_smftp_response(ifd, &cont, ln, maxsize, reader); } while(cont); return res; } int read_smftp_response(int ifd, read_actor *reader) { int res; char server_resp[1024]; res = __read_smftp_response(ifd, server_resp, buf_limit, reader); return res; } void __send_msg(int fd, int num, const char *sep, const char *text, const char *endl) { char numbuf[NUMSIZE+1]; if((num > 1000) || (num < 100)) { syslog(LOG_ERR,"securityalert: ftp message code %d is out of range", num); send_msg(0,500, 0, "ftp message code is out of range"); proxy_exit(); } snprintf(numbuf, NUMSIZE, "%03d", num); strwritev(fd, 4, numbuf, sep, text, endl); } void send_msg(int fd, int num, int cont, const char *text) { __send_msg(fd, num, (cont ? "-" : " "), text, "\r\n"); } void relay_msg(int fd, int num, int cont, const char *text) { __send_msg(fd, num, (cont ? "-(" : " ("), text, ")\r\n"); } /* Commands */ int ____send_noarg(int ofd, const char *cmd) { if(strwritev(ofd, 2, cmd, "\r\n") < 0) { syslog(LOG_ERR, "strwritev(%d) failed: %s", ofd, strerror(errno)); return -1; } return 0; } int ____handle_noarg(int ofd, const char *cmd, int (*retr)(int fd)) { if(____send_noarg(ofd, cmd)) return 999; return retr(ofd); } int ____handle_noarg_resp(int ofd, const char *cmd, int (*retr)(int fd, char *, int), char *resp, int max_size) { if(____send_noarg(ofd, cmd)) return 999; return retr(ofd, resp, max_size); } int ____send_1str(int ofd, const char *cmd, const char *arg) { if(strwritev(ofd, 4, cmd, " ", arg, "\r\n") < 0) { syslog(LOG_ERR, "strwritev(%d) failed: %s", ofd, strerror(errno)); return -1; } return 0; } int ____handle_1str(int ofd, const char *cmd, const char *arg, int (*retr)(int fd)) { if(____send_1str(ofd, cmd, arg)) return 999; return retr(ofd); } int ____handle_1str_resp(int ofd, const char *cmd, const char *arg, int (*retr)(int fd, char *, int), char *resp, int max_size) { if(____send_1str(ofd, cmd, arg)) return 999; return retr(ofd, resp, max_size); }