diff options
Diffstat (limited to 'src/ident.c')
-rw-r--r-- | src/ident.c | 116 |
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 :" | 28 | char *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 | |||
38 | static int | ||
39 | ident_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 | ||
67 | static int | 30 | static int |
68 | crypt_extract_username (char *reply, char **pusername) | 31 | ident_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 | ||
86 | int | 50 | int |
87 | auth_ident (struct sockaddr_in *addr, char **user) | 51 | auth_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 | ||