1 /*
2    map.c
3 
4    This file is part of GNU Anubis.
5    Copyright (C) 2001-2014 The Anubis Team.
6 
7    GNU Anubis is free software; you can redistribute it and/or modify it
8    under the terms of the GNU General Public License as published by the
9    Free Software Foundation; either version 3 of the License, or (at your
10    option) any later version.
11 
12    GNU Anubis is distributed in the hope that it will be useful,
13    but WITHOUT ANY WARRANTY; without even the implied warranty of
14    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15    GNU General Public License for more details.
16 
17    You should have received a copy of the GNU General Public License along
18    with GNU Anubis.  If not, see <http://www.gnu.org/licenses/>.
19 */
20 
21 #include "headers.h"
22 #include "extern.h"
23 #include "rcfile.h"
24 
25 /***************************
26  The translation map parser
27 ****************************/
28 
29 char *
parse_line_option(char * ptr)30 parse_line_option (char *ptr)
31 {
32   while (isspace (*(u_char *) ptr))
33     ptr++;
34 
35   remcrlf (ptr);
36   return ptr;
37 }
38 
39 struct translate_env
40 {
41   int stop;
42   int cs;
43   char *extuser;
44   char *extaddr;
45   char translate[65];
46   char into[65];
47 };
48 
49 void
parse_transmap(int * cs,char * extuser,char * extaddr,char ** dst)50 parse_transmap (int *cs, char *extuser, char *extaddr, char **dst)
51 {
52   struct translate_env env;
53 
54   env.stop = 0;
55   env.cs = -1;			/* failed by default: unmatched */
56   env.extuser = extuser;
57   env.extaddr = extaddr;
58 
59   rcfile_process_section (CF_SUPERVISOR, "TRANSLATION", &env, NULL);
60   *cs = env.cs;
61   if (*cs == 1)
62     {				/* success */
63       if (check_username (env.into))
64 	{
65 	  info (NORMAL, _("%s remapped to %s@localhost."),
66 		env.translate, env.into);
67 	  assign_string (dst, env.into);
68 	}
69       else
70 	*cs = 0;		/* failed: invalid user name */
71     }
72 }
73 
74 
75 /* ******************** Configuration file settings ********************** */
76 #define KW_TRANSLATE           1
77 
78 struct rc_kwdef translate_kw[] = {
79   {"translate", KW_TRANSLATE},
80   {NULL}
81 };
82 
83 
84 void
translate_parser(EVAL_ENV env,int key,ANUBIS_LIST arglist,void * inv_data)85 translate_parser (EVAL_ENV env, int key, ANUBIS_LIST arglist, void *inv_data)
86 {
87   struct translate_env *xlat_env = eval_env_data (env);
88   char *p = 0;
89   int cu = 0;			/* check a user name */
90   char a1[65];
91   char a2[65];
92   char user[65];
93   char address[65];
94   unsigned long inaddr;
95   struct sockaddr_in addr;
96   size_t argc;
97 
98   if (!xlat_env || xlat_env->stop)
99     return;
100 
101   switch (key)
102     {
103     case KW_TRANSLATE:
104       /* translate [=] [USER@]ADDRESS into [=] USERNAME
105          argv[0] = [USER@]ADDRESS
106          argv[1] = "into"
107          argv[2] = USERNAME */
108 
109       safe_strcpy (a1, xlat_env->extaddr);
110       memset (&addr, 0, sizeof (addr));
111 
112       argc = list_count (arglist);
113       if (argc < 3 || argc > 4 || strcmp (list_item (arglist, 1), "into"))
114 	{
115 	  /* FIXME: Merge the two functions? */
116 	  eval_error (0, env, _("invalid syntax"));
117 	  info (VERBOSE, _("Translation map: incorrect syntax."));
118 	  break;
119 	}
120 
121       safe_strcpy (xlat_env->translate, list_item (arglist, 0));
122       p = list_item (arglist, 2);
123       if (p[0] == '=')
124 	p = list_item (arglist, 3);
125       safe_strcpy (xlat_env->into, p);
126 
127       if (strchr (xlat_env->translate, '@'))
128 	{
129 	  if (xlat_env->extuser == 0)
130 	    break;		/* failed */
131 	  safe_strcpy (user, xlat_env->translate);
132 	  p = strchr (user, '@');
133 	  *p++ = '\0';
134 	  safe_strcpy (address, p);
135 	  cu = 1;
136 	}
137       else
138 	safe_strcpy (address, xlat_env->translate);
139 
140       inaddr = inet_addr (address);
141       if (inaddr != INADDR_NONE)
142 	memcpy (&addr.sin_addr, &inaddr, sizeof (inaddr));
143       else
144 	{
145 	  struct hostent *hp = 0;
146 	  hp = gethostbyname (address);
147 	  if (hp == 0)
148 	    {
149 	      cu = 0;
150 	      hostname_error (address);
151 	      break;		/* failed */
152 	    }
153 	  else
154 	    {
155 	      if (hp->h_length != 4 && hp->h_length != 8)
156 		{
157 		  eval_error (0, env,
158 			      _("Illegal address length received for host %s"),
159 			      address);
160 		  cu = 0;
161 		  break;	/* failed */
162 		}
163 	      else
164 		{
165 		  memcpy (&addr.sin_addr.s_addr, hp->h_addr, hp->h_length);
166 		}
167 	    }
168 	}
169 
170       safe_strcpy (a2, inet_ntoa (addr.sin_addr));
171       if (cu)
172 	{
173 	  if (strcmp (xlat_env->extuser, user) == 0)
174 	    {
175 	      /* a temporary solution */
176 	      if (strcmp (a2, "0.0.0.0") == 0)
177 		{
178 		  xlat_env->cs = 1;	/* success */
179 		  xlat_env->stop = 1;
180 		  break;
181 		}
182 	      if (strcmp (a1, a2) == 0)
183 		{
184 		  xlat_env->cs = 1;	/* success */
185 		  xlat_env->stop = 1;
186 		  break;
187 		}
188 	    }
189 	}
190       else if (cu == 0)
191 	{
192 	  /* a temporary solution */
193 	  if (strcmp (a2, "0.0.0.0") == 0)
194 	    {
195 	      xlat_env->cs = 1;	/* success */
196 	      xlat_env->stop = 1;
197 	      break;
198 	    }
199 	  if (strcmp (a1, a2) == 0)
200 	    {
201 	      xlat_env->cs = 1;	/* success */
202 	      xlat_env->stop = 1;
203 	      break;
204 	    }
205 	}
206       break;
207 
208     default:
209       eval_error (2, env,
210 		  _("INTERNAL ERROR at %s:%d: unhandled key %d; "
211 		    "please report"),
212 		  __FILE__, __LINE__,
213 		  key);
214     }
215 }
216 
217 static struct rc_secdef_child translate_secdef_child = {
218   NULL,
219   CF_SUPERVISOR,
220   translate_kw,
221   translate_parser,
222   NULL
223 };
224 
225 void
translate_section_init(void)226 translate_section_init (void)
227 {
228   struct rc_secdef *sp = anubis_add_section ("TRANSLATION");
229   rc_secdef_add_child (sp, &translate_secdef_child);
230 }
231 
232 /* EOF */
233