33 |
#endif /* USE_LIBWRAP */ |
#endif /* USE_LIBWRAP */ |
34 |
|
|
35 |
static RETSIGTYPE sig_cld(int); |
static RETSIGTYPE sig_cld(int); |
|
static void service_unavailable(int); |
|
|
static void set_unprivileged_user(void); |
|
36 |
|
|
37 |
static int nchild; |
static int nchild; |
38 |
|
|
102 |
then close a transmission channel. |
then close a transmission channel. |
103 |
*************************************/ |
*************************************/ |
104 |
|
|
105 |
static void |
void |
106 |
service_unavailable(int sd_client) |
service_unavailable(int sd_client) |
107 |
{ |
{ |
108 |
char buf[LINEBUFFER+1]; |
char buf[LINEBUFFER+1]; |
121 |
(if possible). |
(if possible). |
122 |
**************************/ |
**************************/ |
123 |
|
|
124 |
static void |
void |
125 |
set_unprivileged_user(void) |
set_unprivileged_user(void) |
126 |
{ |
{ |
127 |
if (topt & T_USER_NOTPRIVIL) { |
if (topt & T_USER_NOTPRIVIL) { |
138 |
return; |
return; |
139 |
} |
} |
140 |
|
|
141 |
|
int |
142 |
|
anubis_child_main (int sd_client, struct sockaddr_in *addr) |
143 |
|
{ |
144 |
|
int rc; |
145 |
|
|
146 |
|
#if defined(WITH_GSASL) |
147 |
|
switch (anubis_mode) { |
148 |
|
case anubis_transparent: |
149 |
|
rc = anubis_transparent_mode (sd_client, addr); |
150 |
|
break; |
151 |
|
|
152 |
|
case anubis_authenticate: |
153 |
|
rc = anubis_authenticate_mode (sd_client, addr); |
154 |
|
} |
155 |
|
#else |
156 |
|
rc = anubis_transparent_mode (sd_client, addr); |
157 |
|
#endif |
158 |
|
close_socket(sd_client); |
159 |
|
return rc; |
160 |
|
} |
161 |
|
|
162 |
/************** |
/************** |
163 |
DAEMON loop |
DAEMON loop |
164 |
***************/ |
***************/ |
169 |
struct sockaddr_in addr; |
struct sockaddr_in addr; |
170 |
pid_t childpid = 0; |
pid_t childpid = 0; |
171 |
int sd_client = 0; |
int sd_client = 0; |
|
int sd_server = 0; |
|
172 |
socklen_t addrlen; |
socklen_t addrlen; |
173 |
#ifdef USE_LIBWRAP |
#ifdef USE_LIBWRAP |
174 |
struct request_info req; |
struct request_info req; |
233 |
if (childpid == -1) |
if (childpid == -1) |
234 |
anubis_error(HARD, _("daemon: Can't fork. %s."), strerror(errno)); |
anubis_error(HARD, _("daemon: Can't fork. %s."), strerror(errno)); |
235 |
else if (childpid == 0) { /* a child process */ |
else if (childpid == 0) { /* a child process */ |
236 |
int rs = 0; |
/* FIXME */ |
|
int cs = 0; |
|
237 |
signal(SIGCHLD, SIG_IGN); |
signal(SIGCHLD, SIG_IGN); |
238 |
|
quit(anubis_child_main(sd_client, &addr)); |
|
rs = auth_ident(&addr, |
|
|
session.client, |
|
|
sizeof(session.client)); |
|
|
|
|
|
if ((topt & T_DROP_UNKNOWN_USER) && !rs) { |
|
|
service_unavailable(sd_client); |
|
|
quit(0); |
|
|
} |
|
|
|
|
|
parse_transmap(&cs, |
|
|
rs ? session.client : 0, |
|
|
inet_ntoa(addr.sin_addr), |
|
|
session.client, |
|
|
sizeof(session.client)); |
|
|
|
|
|
if (cs == 1) { |
|
|
anubis_changeowner(session.client); |
|
|
auth_tunnel(); |
|
|
} |
|
|
else if (rs |
|
|
&& cs == -1 |
|
|
&& ntohl(addr.sin_addr.s_addr) |
|
|
== INADDR_LOOPBACK) { |
|
|
if (check_username(session.client)) { |
|
|
anubis_changeowner(session.client); |
|
|
auth_tunnel(); |
|
|
} |
|
|
else |
|
|
set_unprivileged_user(); |
|
|
} |
|
|
else |
|
|
set_unprivileged_user(); |
|
|
|
|
|
if (!(topt & T_LOCAL_MTA) |
|
|
&& strlen(session.mta) == 0) { |
|
|
anubis_error(HARD, _("The MTA has not been specified. " |
|
|
"Set the REMOTE-MTA or LOCAL-MTA.")); |
|
|
close_socket(sd_client); |
|
|
quit(EXIT_FAILURE); |
|
|
} |
|
|
|
|
|
/* |
|
|
Protection against a loop connection. |
|
|
*/ |
|
|
|
|
|
if (!(topt & T_LOCAL_MTA)) { |
|
|
unsigned long inaddr; |
|
|
struct sockaddr_in ad; |
|
|
|
|
|
memset(&ad, 0, sizeof(ad)); |
|
|
inaddr = inet_addr(session.mta); |
|
|
if (inaddr != INADDR_NONE) |
|
|
memcpy(&ad.sin_addr, &inaddr, sizeof(inaddr)); |
|
|
else { |
|
|
struct hostent *hp = 0; |
|
|
hp = gethostbyname(session.mta); |
|
|
if (hp == 0) { |
|
|
hostname_error(session.mta); |
|
|
close_socket(sd_client); |
|
|
quit(EXIT_FAILURE); |
|
|
} |
|
|
else { |
|
|
if (hp->h_length != 4 && hp->h_length != 8) { |
|
|
anubis_error(HARD, |
|
|
_("Illegal address length received for host %s"), session.mta); |
|
|
close_socket(sd_client); |
|
|
quit(EXIT_FAILURE); |
|
|
} |
|
|
else { |
|
|
memcpy((char *)&ad.sin_addr.s_addr, hp->h_addr, |
|
|
hp->h_length); |
|
|
} |
|
|
} |
|
|
} |
|
|
if (ntohl(ad.sin_addr.s_addr) == INADDR_LOOPBACK |
|
|
&& session.tunnel_port == session.mta_port) { |
|
|
anubis_error(SOFT, _("Loop not allowed. Connection rejected.")); |
|
|
close_socket(sd_client); |
|
|
quit(EXIT_FAILURE); |
|
|
} |
|
|
} |
|
|
|
|
|
alarm(300); |
|
|
if (topt & T_LOCAL_MTA) { |
|
|
sd_server = make_local_connection(session.execpath, session.execargs); |
|
|
if (sd_server == -1) { |
|
|
service_unavailable(sd_client); |
|
|
quit(EXIT_FAILURE); |
|
|
} |
|
|
} |
|
|
else { |
|
|
sd_server = make_remote_connection(session.mta, session.mta_port); |
|
|
if (sd_server == -1) |
|
|
service_unavailable(sd_client); |
|
|
} |
|
|
alarm(0); |
|
|
|
|
|
if (!(topt & T_ERROR)) { |
|
|
remote_client = (void *)sd_client; |
|
|
remote_server = (void *)sd_server; |
|
|
alarm(900); |
|
|
smtp_session(); |
|
|
alarm(0); |
|
|
|
|
|
#ifdef USE_SSL |
|
|
net_close(CLIENT, secure.client); |
|
|
net_close(SERVER, secure.server); |
|
|
secure.server = 0; |
|
|
secure.client = 0; |
|
|
#endif |
|
|
} |
|
|
close_socket(sd_server); |
|
|
close_socket(sd_client); |
|
|
|
|
|
if (topt & T_ERROR) |
|
|
info(NORMAL, _("Connection terminated.")); |
|
|
else |
|
|
info(NORMAL, _("Connection closed successfully.")); |
|
|
|
|
|
#ifdef HAVE_PAM |
|
|
pam_retval = pam_close_session(pamh, 0); |
|
|
if (pam_retval == PAM_SUCCESS) |
|
|
info(VERBOSE, _("PAM: Session closed.")); |
|
|
if (pam_end(pamh, pam_retval) != PAM_SUCCESS) { |
|
|
pamh = NULL; |
|
|
info(NORMAL, _("PAM: failed to release authenticator.")); |
|
|
quit(EXIT_FAILURE); |
|
|
} |
|
|
#endif /* HAVE_PAM */ |
|
|
|
|
|
quit(0); |
|
239 |
} |
} |
240 |
close_socket(sd_client); |
close_socket(sd_client); |
241 |
} |
} |
330 |
remote_server = (void *)sd_server; |
remote_server = (void *)sd_server; |
331 |
net_set_io(CLIENT, _stdio_read, _stdio_write, NULL, _stdio_strerror); |
net_set_io(CLIENT, _stdio_read, _stdio_write, NULL, _stdio_strerror); |
332 |
net_set_io(SERVER, _stdio_read, _stdio_write, NULL, _stdio_strerror); |
net_set_io(SERVER, _stdio_read, _stdio_write, NULL, _stdio_strerror); |
333 |
smtp_session(); |
smtp_session_transparent(); |
334 |
cleanup_children(); |
cleanup_children(); |
335 |
|
|
336 |
close_socket(sd_server); |
close_socket(sd_server); |