3 * Identifies and logs the client of a connection
5 * (c) 1999 Straylight/Edgeware
8 /*----- Licensing notice --------------------------------------------------*
10 * This file is part of the `fwd' port forwarder.
12 * `fwd' is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License as published by
14 * the Free Software Foundation; either version 2 of the License, or
15 * (at your option) any later version.
17 * `fwd' is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 * GNU General Public License for more details.
22 * You should have received a copy of the GNU General Public License
23 * along with `fwd'; if not, write to the Free Software Foundation,
24 * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
29 /*----- Magic numbers -----------------------------------------------------*/
31 #define TIMEOUT 15 /* Seconds to wait for answers */
33 /*----- Data structures ---------------------------------------------------*/
35 /* --- Structure to track the progress of an identification --- */
38 id_req q
; /* Copy of client's request block */
39 time_t when
; /* When the connection occurred */
40 conn c
; /* Connection selector */
41 unsigned state
; /* Current state of the world */
42 sel_timer t
; /* Timeout selector */
43 bres_client r
; /* Backgd resolver client block */
44 ident_request i
; /* Ident client block */
45 char host
[128]; /* Resolved hostname */
46 char user
[64]; /* Authenticated client user */
49 #define S_HOST 1u /* Read the hostname from resolver */
50 #define S_USER 2u /* Read the username from RFC931 */
51 #define S_TIMER 4u /* Timeout has completed */
53 /*----- Main code ---------------------------------------------------------*/
55 /* --- @id_done@ --- *
57 * Arguments: @id *i@ = pointer to identification block
61 * Use: Finishes with an identification block.
64 static void id_done(id
*i
)
66 /* --- Close down the various dependent bits --- */
68 if (!(i
->state
& S_HOST
))
70 if (!(i
->state
& S_USER
))
72 if (!(i
->state
& S_TIMER
))
75 /* --- Report the final result --- */
77 fw_log(i
->when
, "[%s] %s from %s@%s [%s:%u]",
80 inet_ntoa(i
->q
.rsin
.sin_addr
), (unsigned)ntohs(i
->q
.rsin
.sin_port
));
82 /* --- Dispose of the block --- */
90 * Arguments: @struct hostent *h@ = name of the resolved host
91 * @void *vp@ = pointer to identification block
95 * Use: Responds to a completed reverse name resolution.
98 static void id_res(struct hostent
*h
, void *vp
)
102 str_sanitize(i
->host
, h
->h_name
, sizeof(i
->host
));
104 if (i
->state
& S_USER
)
108 /* --- @id_ident@ --- *
110 * Arguments: @ident_reply *i@ = pointer to string read from server
111 * @void *vp@ = pointer to identification block
115 * Use: Responds to a line read from the remote RFC931 server.
118 static void id_ident(ident_reply
*ir
, void *vp
)
122 /* --- Read the information from the client --- */
124 if (ir
&& ir
->type
== IDENT_USERID
)
125 str_sanitize(i
->user
, ir
->u
.userid
.user
, sizeof(i
->user
));
127 /* --- Maybe finish off this identification --- */
130 if (i
->state
& S_HOST
)
134 /* --- @id_timer@ --- *
136 * Arguments: @struct timeval *tv@ = pointer to the current time
137 * @void *vp@ = pointer to identification block
141 * Use: Times an identification job out.
144 static void id_timer(struct timeval
*tv
, void *vp
)
151 /* --- @identify@ --- *
153 * Arguments: @const id_req *q@ = pointer to request block
157 * Use: Starts a background ident lookup and reverse-resolve job
158 * which will, eventually, report a message to the system log.
161 void identify(const id_req
*q
)
165 /* --- Initialize the block with stuff --- */
167 i
= xmalloc(sizeof(*i
));
171 str_sanitize(i
->host
, inet_ntoa(q
->rsin
.sin_addr
), sizeof(i
->host
));
172 strcpy(i
->user
, "<ANONYMOUS>");
176 /* --- Set up the connection to the identity server --- */
178 ident(&i
->i
, sel
, &q
->lsin
, &q
->rsin
, id_ident
, i
);
180 /* --- Set up the name resolver --- */
182 bres_byaddr(&i
->r
, q
->rsin
.sin_addr
, id_res
, i
);
184 /* --- Set up the time limiter --- */
188 gettimeofday(&tv
, 0);
189 tv
.tv_sec
+= TIMEOUT
;
190 sel_addtimer(sel
, &i
->t
, &tv
, id_timer
, i
);
194 /*----- That's all, folks -------------------------------------------------*/