rfc931.c
上传用户:minyiyu
上传日期:2018-12-24
资源大小:864k
文件大小:4k
源码类别:

Telnet服务器

开发平台:

Unix_Linux

  1.  /*
  2.   * rfc931_user() speaks a common subset of the RFC 931, AUTH, TAP and IDENT
  3.   * protocols. It consults an RFC 931 etc. compatible daemon on the client
  4.   * host to look up the remote user name. The information should not be used
  5.   * for authentication purposes.
  6.   * 
  7.   * Diagnostics are reported through syslog(3).
  8.   * 
  9.   * Author: Wietse Venema, Eindhoven University of Technology, The Netherlands.
  10.   * 
  11.   * Inspired by the authutil package (comp.sources.unix volume 22) by Dan
  12.   * Bernstein (brnstnd@kramden.acf.nyu.edu).
  13.   */
  14. #ifndef lint
  15. static char sccsid[] = "@(#) rfc931.c 1.4 93/03/07 22:47:52";
  16. #endif
  17. #include <stdio.h>
  18. #include <syslog.h>
  19. #include <sys/types.h>
  20. #include <sys/socket.h>
  21. #include <netinet/in.h>
  22. #include <setjmp.h>
  23. #include <signal.h>
  24. /*#include "log_tcp.h"*/
  25. #define RFC931_PORT 113 /* Semi-well-known port */
  26. #ifndef RFC931_TIMEOUT
  27. #define RFC931_TIMEOUT 30 /* wait for at most 30 seconds */
  28. #endif
  29. extern char *strchr();
  30. extern char *inet_ntoa();
  31. static jmp_buf timebuf;
  32. /* timeout - handle timeouts */
  33. static void 
  34. timeout(sig)
  35. int     sig;
  36. {
  37. longjmp(timebuf, sig);
  38. }
  39. /* rfc931_name - return remote user name */
  40. char   *
  41. my_rfc931_name(herefd, there)
  42. int     herefd;
  43. struct sockaddr_in *there; /* remote link information */
  44. {
  45. struct sockaddr_in here;/* local link information */
  46. struct sockaddr_in sin; /* for talking to RFC931 daemon */
  47. int     length;
  48. int     s;
  49. unsigned remote;
  50. unsigned local;
  51. static char user[256]; /* XXX */
  52. char    buffer[512]; /* YYY */
  53. FILE   *fp;
  54. char   *cp;
  55. char   *result = "unknown";
  56. /* Find out local address and port number of stdin. */
  57. length = sizeof(here);
  58. if (getsockname(herefd, (struct sockaddr *) & here, &length) == -1) {
  59. syslog(LOG_ERR, "getsockname: %m");
  60. return (result);
  61. }
  62. /*
  63.  * The socket that will be used for user name lookups should be bound
  64.  * to the same local IP address as stdin. This will automagically
  65.  * happen on hosts that have only one IP network address. When the
  66.  * local host has more than one IP network address, we must do an
  67.  * explicit bind() call.
  68.  */
  69. if ((s = socket(AF_INET, SOCK_STREAM, 0)) == -1)
  70. return (result);
  71. sin = here;
  72. sin.sin_port = 0;
  73. if (bind(s, (struct sockaddr *) & sin, sizeof sin) < 0) {
  74. syslog(LOG_ERR, "bind: %s: %m", inet_ntoa(here.sin_addr));
  75. return (result);
  76. }
  77. /* Set up timer so we won't get stuck. */
  78. signal(SIGALRM, timeout);
  79. if (setjmp(timebuf)) {
  80. close(s); /* not: fclose(fp) */
  81. return (result);
  82. }
  83. alarm(RFC931_TIMEOUT);
  84. /* Connect to the RFC931 daemon. */
  85. sin = *there;
  86. sin.sin_port = htons(RFC931_PORT);
  87. if (connect(s, (struct sockaddr *) & sin, sizeof(sin)) == -1
  88. || (fp = fdopen(s, "w+")) == 0) {
  89. close(s);
  90. alarm(0);
  91. return (result);
  92. }
  93. /*
  94.  * Use unbuffered I/O or we may read back our own query. setbuf()
  95.  * must be called before doing any I/O on the stream. Thanks for the
  96.  * reminder, Paul Kranenburg <pk@cs.few.eur.nl>!
  97.  */
  98. setbuf(fp, (char *) 0);
  99. /* Query the RFC 931 server. Would 13-byte writes ever be broken up? */
  100. fprintf(fp, "%u,%urn", ntohs(there->sin_port), ntohs(here.sin_port));
  101. fflush(fp);
  102. /*
  103.  * Read response from server. Use fgets()/sscanf() instead of
  104.  * fscanf() because there is no buffer for pushback. Thanks, Chris
  105.  * Turbeville <turbo@cse.uta.edu>.
  106.  */
  107. if (fgets(buffer, sizeof(buffer), fp) != 0
  108. && ferror(fp) == 0 && feof(fp) == 0
  109. && sscanf(buffer, "%u , %u : USERID :%*[^:]:%255s",
  110. &remote, &local, user) == 3
  111. && ntohs(there->sin_port) == remote
  112. && ntohs(here.sin_port) == local) {
  113. /* Strip trailing carriage return. */
  114. if (cp = strchr(user, 'r'))
  115. *cp = 0;
  116. result = user;
  117. }
  118. alarm(0);
  119. fclose(fp);
  120. return (result);
  121. }