aboutsummaryrefslogtreecommitdiff
path: root/src/ident.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/ident.c')
-rw-r--r--src/ident.c116
1 files changed, 36 insertions, 80 deletions
diff --git a/src/ident.c b/src/ident.c
index 950f9a4..eca5033 100644
--- a/src/ident.c
+++ b/src/ident.c
@@ -2,7 +2,7 @@
2 ident.c 2 ident.c
3 3
4 This file is part of GNU Anubis. 4 This file is part of GNU Anubis.
5 Copyright (C) 2001-2014 The Anubis Team. 5 Copyright (C) 2001-2024 The Anubis Team.
6 6
7 GNU Anubis is free software; you can redistribute it and/or modify it 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 8 under the terms of the GNU General Public License as published by the
@@ -25,66 +25,30 @@
25 IDENT protocol support 25 IDENT protocol support
26************************/ 26************************/
27 27
28#define USERNAME_C "USERID :" 28char *identd_keyfile_name;
29
30/* If the reply matches sscanf expression
31
32 "%*[^:]: USERID :%*[^:]:%s"
33
34 and the length of "%s" part does not exceed size-1 bytes,
35 copies this part to USERNAME and returns 0. Otherwise,
36 returns 1 */
37
38static int
39ident_extract_username (char *reply, char **pusername)
40{
41 char *p;
42
43 p = strchr (reply, ':');
44 if (!p)
45 return 1;
46 if (p[1] != ' ' || strncmp (p + 2, USERNAME_C, sizeof (USERNAME_C) - 1))
47 return 1;
48 p += 2 + sizeof (USERNAME_C) - 1;
49 p = strchr (p, ':');
50 if (!p)
51 return 1;
52 do
53 p++;
54 while (*p == ' ');
55 assign_string (pusername, p);
56 return 0;
57}
58
59/* If the reply matches sscanf expression
60
61 "%*[^ ] %*[^ ] %*[^ ] %*[^ ] %*[^ ] %s"
62
63 and the length of "%s" part does not exceed size-1 bytes,
64 copies this part to USERNAME and returns 0. Otherwise,
65 returns 1 */
66 29
67static int 30static int
68crypt_extract_username (char *reply, char **pusername) 31ident_extract_username (char const *reply, char **pusername)
69{ 32{
70 int i; 33 struct wordsplit ws = { .ws_delim = ":" };
71 char *p = reply; 34 int wsflags = WRDSF_NOVAR | WRDSF_NOCMD | WRDSF_DELIM | WRDSF_WS;
72#define skip_word(c) while (*c && (*c) != ' ') c++ 35 int result = 1;
73 36
74 /* Skip five words */ 37 if (wordsplit (reply, &ws, wsflags))
75 for (i = 0; i < 5; i++)
76 { 38 {
77 skip_word (p); 39 anubis_error (0, 0, _("wordsplit failed: %s"), wordsplit_strerror (&ws));
78 if (!*p++)
79 return 1;
80 } 40 }
81 41 else if (ws.ws_wordc == 4 && strcmp (ws.ws_wordv[1], "USERID") == 0)
82 assign_string (pusername, p); 42 {
83 return 0; 43 *pusername = xstrdup (ws.ws_wordv[3]);
44 result = 0;
45 }
46 wordsplit_free (&ws);
47 return result;
84} 48}
85 49
86int 50int
87auth_ident (struct sockaddr_in *addr, char **user) 51auth_ident (struct sockaddr_in *addr, char **ret_user)
88{ 52{
89 struct servent *sp; 53 struct servent *sp;
90 struct sockaddr_in ident; 54 struct sockaddr_in ident;
@@ -95,7 +59,9 @@ auth_ident (struct sockaddr_in *addr, char **user)
95 int rc; 59 int rc;
96 NET_STREAM str; 60 NET_STREAM str;
97 size_t nbytes; 61 size_t nbytes;
98 62 char *user;
63 int ulen;
64
99 if ((sd = socket (AF_INET, SOCK_STREAM, 0)) < 0) 65 if ((sd = socket (AF_INET, SOCK_STREAM, 0)) < 0)
100 { 66 {
101 anubis_error (0, errno, _("IDENT: socket() failed")); 67 anubis_error (0, errno, _("IDENT: socket() failed"));
@@ -141,7 +107,7 @@ auth_ident (struct sockaddr_in *addr, char **user)
141 net_close_stream (&str); 107 net_close_stream (&str);
142 108
143 remcrlf (buf); 109 remcrlf (buf);
144 if (ident_extract_username (buf, user)) 110 if (ident_extract_username (buf, &user))
145 { 111 {
146 info (VERBOSE, _("IDENT: incorrect data.")); 112 info (VERBOSE, _("IDENT: incorrect data."));
147 free (buf); 113 free (buf);
@@ -152,37 +118,27 @@ auth_ident (struct sockaddr_in *addr, char **user)
152 /****************************** 118 /******************************
153 IDENTD DES decryption support 119 IDENTD DES decryption support
154 *******************************/ 120 *******************************/
155 121 ulen = strlen (user);
156 if (strstr (*user, "[") && strstr (*user, "]")) 122 if (ulen > 2 && user[0] == '[' && user[ulen-1] == ']')
157 { 123 {
158 int rs = 0; 124 char *s;
159 info (VERBOSE, _("IDENT: data probably encrypted with DES...")); 125
160 external_program (&rs, IDECRYPT_PATH, *user, buf, LINEBUFFER); 126 s = idecrypt_username (user + 1, ulen - 2);
161 if (rs == -1) 127 free (user);
162 return 0; 128 if (s != NULL)
163
164 remcrlf (buf);
165 if (crypt_extract_username (buf, user))
166 { 129 {
167 info (VERBOSE, _("IDENT: incorrect data (DES deciphered).")); 130 user = s;
168 return 0; 131 info (VERBOSE, _("IDENT: data encrypted with DES"));
169 } 132 }
170 else 133 else
171 { /* UID deciphered */ 134 {
172 if (ntohl (ident.sin_addr.s_addr) == INADDR_LOOPBACK) 135 info (VERBOSE, _("IDENT: incorrect data (DES deciphered)."));
173 { 136 *ret_user = NULL;
174 struct passwd *pwd; 137 return 0;
175 int uid = atoi (*user);
176 pwd = getpwuid (uid);
177 if (pwd != 0)
178 assign_string (user, pwd->pw_name);
179 else
180 return 0;
181 }
182 } 138 }
183 } 139 }
184 140 *ret_user = user;
185 info (VERBOSE, _("IDENT: resolved remote user to %s."), *user); 141 info (VERBOSE, _("IDENT: resolved remote user to %s."), user);
186 return 1; /* success */ 142 return 1; /* success */
187} 143}
188 144

Return to:

Send suggestions and report system problems to the System administrator.