3 sffingerd.c - SourceForge's crazy little fingerd
4 do-anything-you-want-with-it-don't-blame-me-for-anything license.
6 Mukund <muks@users.sourceforge.net>
9 #undef LOG_REQUESTS if you don't wanna log any users requests.
11 gcc -s -I/path/to/mysql/include -o sffingerd sffingerd.c -L/path/to/mysql/lib/mysql -lmysqlclient
12 cp -f sffingerd /usr/local/sbin
14 MUST BE RUN UNDER inetd
15 finger stream tcp nowait nobody /usr/local/sbin/sffingerd fingerd
21 #define MYSQL_HOST "localhost" // EDIT THIS
22 #define MYSQL_DATABASE "sourceforge"
23 #define MYSQL_USER "root"
24 #define MYSQL_PASSWORD ""
32 #include <sys/types.h>
36 #include <sys/socket.h>
37 #include <netinet/in.h>
38 #include <arpa/inet.h>
42 int main(int argc, char *argv[])
45 struct sockaddr_in name;
47 unsigned long int remote;
50 char remote_machine[1024];
55 MYSQL_RES *user_result, *group_result;
56 MYSQL_ROW user_row, group_row;
60 openlog("sffingerd", (LOG_CONS | LOG_PID), LOG_DAEMON);
64 syslog(LOG_ERR, "can't run sffingerd as root");
65 fprintf(stderr, "can't run sffingerd as root\n");
71 length = sizeof(name);
72 if (getpeername(0, (struct sockaddr *) &name, &length) == -1)
74 perror("getpeername");
75 syslog(LOG_ERR, "getpeername: %m");
80 if (name.sin_family != AF_INET)
82 syslog(LOG_ERR, "connection not from INET family");
83 fprintf(stderr, "connection not from INET family\n");
88 remote = ntohl(name.sin_addr.s_addr);
89 remote_ip = inet_ntoa(name.sin_addr);
91 if ((host = gethostbyaddr((char *) &name.sin_addr,
92 sizeof(struct in_addr), AF_INET)) != NULL)
93 snprintf(remote_machine, 1023, "%.512s [%.15s]", host->h_name, remote_ip);
95 snprintf(remote_machine, 1023, "%.15s [%.15s]", remote_ip, remote_ip);
98 // get the query string - i.e., the username
100 if (fgets(user, 255, stdin) == NULL)
102 syslog(LOG_ERR, "fgets failed - no input string?");
103 fprintf(stdout, "fgets failed - no input string?\n");
108 // strip out the \n and \r at the end of the username
109 // in the query and terminate the string there
111 for (l = 0; user[l]; l++)
113 if ((user[l] == '\r') || (user[l] == '\n'))
121 syslog(LOG_INFO, "finger request from host %s for user '%s'", remote_machine, user);
124 fprintf(stdout, "\nWelcome to SourceForge's Finger Service!\n"
125 "----------------------------------------\n\n");
127 // check for valid sourceforge username
128 // taken from www/include/account.php -> account_namevalid()
130 if ((strchr(user, ' ') != NULL) ||
131 (strspn(user, "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-_") != strlen(user)) ||
132 (strlen(user) < 3) || (strlen(user) > 15))
134 fprintf(stdout, "You have supplied a malformed username for a SourceForge developer.\n"
135 "Please try again with a legal username. Thank you.\n\n\n");
140 // hmm. fine. now connect to the mysql database
141 // and check if the user exists.
145 if ((sock = mysql_real_connect(&mysql, MYSQL_HOST,
146 MYSQL_USER, MYSQL_PASSWORD, MYSQL_DATABASE, 0, NULL, 0)) == NULL)
148 syslog(LOG_ERR, "unable to connect to the MYSQL database");
149 fprintf(stderr, "unable to connect to the MYSQL database\n");
154 snprintf(qbuf, 4095, "SELECT user_id, user_name, realname, people_view_skills, people_resume, add_date FROM users WHERE user_name='%s'", user);
156 if (mysql_query(sock, qbuf) != 0)
158 syslog(LOG_ERR, "MYSQL SELECT FROM user query failed [%s]", mysql_error(sock));
159 fprintf(stderr, "MYSQL SELECT FROM user query failed [%s]\n", mysql_error(sock));
165 if ((user_result = mysql_store_result(sock)) == NULL)
167 syslog(LOG_ERR, "mysql_store_result() failed [%s]", mysql_error(sock));
168 fprintf(stderr, "mysql_store_result() failed [%s]\n", mysql_error(sock));
174 if ((count = mysql_num_rows(user_result)) > 1)
176 syslog(LOG_ERR, "mysql_num_rows() for user '%s' returned more than one record!", user);
177 fprintf(stderr, "mysql_num_rows() for user '%s' returned more than one record!\n", user);
178 mysql_free_result(user_result);
187 syslog(LOG_ERR, "query for user '%s' from host %s didn't happen. user's unknown here.", user, remote_machine);
189 fprintf(stdout, "\nThe username you supplied is unknown here. That user does not exist.\n");
193 user_row = mysql_fetch_row(user_result);
195 fprintf(stdout, "\nPersonal Information:\n\n");
196 fprintf(stdout, "\tUserID : %s\n\tUsername : %s\n", user_row[0], user_row[1]);
197 fprintf(stdout, "\tE-mail : %s@users.sourceforge.net\n\tRealname : %s\n", user_row[1], user_row[2]);
199 addtime = atoi(user_row[5]);
200 fprintf(stdout, "\nMember on SourceForge since %s", ctime(&addtime));
202 snprintf(qbuf, 4095, "SELECT groups.group_name, groups.group_id, groups.unix_group_name "
203 "FROM groups, user_group WHERE user_group.user_id = '%s' AND "
204 "groups.group_id = user_group.group_id AND "
205 "groups.is_public=1", user_row[0]);
207 if (mysql_query(sock, qbuf) != 0)
209 syslog(LOG_ERR, "MYSQL SELECT FROM groups, user_group query failed [%s]", mysql_error(sock));
210 fprintf(stderr, "MYSQL SELECT FROM groups, user_group query failed [%s]\n", mysql_error(sock));
211 mysql_free_result(user_result);
217 if ((group_result = mysql_store_result(sock)) == NULL)
219 syslog(LOG_ERR, "mysql_store_result() failed [%s]", mysql_error(sock));
220 fprintf(stderr, "mysql_store_result() failed [%s]\n", mysql_error(sock));
221 mysql_free_result(user_result);
228 count = mysql_num_rows(group_result);
232 fprintf(stdout, "\n\nThe user does not belong in any groups.\n");
236 fprintf(stdout, "\n\nMember of the following groups:\n\n");
238 while ((group_row = mysql_fetch_row(group_result)) != NULL)
239 fprintf(stdout, "\to %s (http://sourceforge.net/projects/%s/)\n", group_row[0], group_row[2]);
242 mysql_free_result(group_result);
244 if (atoi(user_row[3]) != 1)
245 fprintf(stdout, "\n\nThe user has set his/her profile to private.\n");
248 fprintf(stdout, "\n\nProfile follows:\n\n");
249 fprintf(stdout, "%s\n\n", user_row[4]);
254 mysql_free_result(user_result);
257 fprintf(stdout, "\n\n---------------------------------------------------------------------\n"
258 "For FREE hosting, forums, mailing lists, CVS, shell, db, bug tracking,\n"
259 "and more for Open Source projects, come to http://sourceforge.net/\n");
261 fprintf(stdout, "\n");
265 return 0; // darn_compiler();