⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 rlogind.c

📁 linux下常用的网络工具的代码
💻 C
📖 第 1 页 / 共 3 页
字号:
  if (verify_hostname || in_local_domain (ap->hostname))    {      int             match = 0;      for (hp = gethostbyname (ap->hostname); hp && !match; hp->h_addr_list++)	{	  if (hp->h_addr_list[0] == NULL)	    break;	  match = memcmp (hp->h_addr_list[0], &ap->from.sin_addr,			  sizeof (ap->from.sin_addr)) == 0;	}      if (!match)	{	  syslog (LOG_ERR | LOG_AUTH, "cannot find matching IP for %s (%s)",		  ap->hostname, inet_ntoa (ap->from.sin_addr));	  fatal (fd, "Permission denied", 0);	}    }#if defined(KERBEROS) || defined(SHISHI)  if (kerberos)    {      const char     *err_msg;      int             c = 0;      if (do_krb_login (fd, ap, &err_msg) == 0)	authenticated++;      else	fatal (fd, err_msg, 0);      write (fd, &c, 1);      confirmed = 1;		/* we sent the null! */    }  else#endif    {      int             port = ntohs (ap->from.sin_port);      if (ap->from.sin_family != AF_INET ||	  port >= IPPORT_RESERVED || port < IPPORT_RESERVED / 2)	{	  syslog (LOG_NOTICE, "Connection from %s on illegal port %d",		  inet_ntoa (ap->from.sin_addr), port);	  fatal (fd, "Permission denied", 0);	}#ifdef IP_OPTIONS      {	u_char          optbuf[BUFSIZ / 3], *cp;	char            lbuf[BUFSIZ], *lp;	int             optsize = sizeof (optbuf), ipproto;	struct protoent *ip;	if ((ip = getprotobyname ("ip")) != NULL)	  ipproto = ip->p_proto;	else	  ipproto = IPPROTO_IP;	if (getsockopt (0, ipproto, IP_OPTIONS, (char *) optbuf,			&optsize) == 0 && optsize != 0)	  {	    lp = lbuf;	    for (cp = optbuf; optsize > 0; cp++, optsize--, lp += 3)	      sprintf (lp, " %2.2x", *cp);	    syslog (LOG_NOTICE, "Ignoring IP options: %s", lbuf);	    if (setsockopt (0, ipproto, IP_OPTIONS, (char *) NULL, optsize))	      {		syslog (LOG_ERR, "setsockopt IP_OPTIONS NULL: %m");		exit (1);	      }	  }      }#endif /* IP_OPTIONS */      if (do_rlogin (fd, ap) == 0)	authenticated++;    }  if (confirmed == 0)    {      write (fd, "", 1);      confirmed = 1;		/* we sent the null! */    }#ifdef SHISHI  len = sizeof (SECURE_MESSAGE) - 1;  IF_ENCRYPT (writeenc	      (ap->h, fd, SECURE_MESSAGE, len, &c, &ap->iv2, ap->enckey,	       ap->protocol));#else  IF_ENCRYPT (des_write (fd, SECURE_MESSAGE, sizeof (SECURE_MESSAGE) - 1));#endif  return authenticated;}voidsetup_tty (int fd, struct auth_data *ap){  register char  *cp = strchr (ap->term + ENVSIZE, '/');  char           *speed;  struct termios  tt;  tcgetattr (fd, &tt);  if (cp)    {      *cp++ = '\0';      speed = cp;      cp = strchr (speed, '/');      if (cp)	*cp++ = '\0';#ifdef HAVE_CFSETSPEED      cfsetspeed (&tt, strtoul (speed, NULL, 10));#else      cfsetispeed (&tt, strtoul (speed, NULL, 10));      cfsetospeed (&tt, strtoul (speed, NULL, 10));#endif    }  tt.c_iflag = TTYDEF_IFLAG;  tt.c_oflag = TTYDEF_OFLAG;  tt.c_lflag = TTYDEF_LFLAG;  tcsetattr (fd, TCSAFLUSH, &tt);  ap->env[0] = ap->term;  ap->env[1] = 0;}#ifdef UTMPXchar           *utmp_ptsid ();/*FIXME*/ void  utmp_init ();voidsetup_utmp (char *line){  char           *ut_id = utmp_ptsid (line, "rl");  utmp_init (line + sizeof ("/dev/") - 1, ".rlogin", ut_id);}#else# define setup_utmp(line)#endifvoidexec_login (int authenticated, struct auth_data *ap){  if (authenticated)    {#ifdef SOLARIS      execle (path_login, "login", "-p",	      "-h", ap->hostname, ap->term, "-f", "--",	      ap->lusername, NULL, ap->env);#else      execle (path_login, "login", "-p",	      "-h", ap->hostname, "-f", ap->lusername, NULL, ap->env);#endif    }  else    {#ifdef SOLARIS      execle (path_login, "login", "-p",	      "-h", ap->hostname, ap->term, "--",	      ap->lusername, NULL, ap->env);#else      execle (path_login, "login", "-p",	      "-h", ap->hostname, ap->lusername, NULL, ap->env);#endif    }  syslog (LOG_ERR, "can't exec login: %m");}intrlogind_mainloop (int infd, int outfd){  size_t          size;  struct auth_data auth_data;  int             true;  char            c;  int             authenticated;  pid_t           pid;  int             master;  memset (&auth_data, 0, sizeof auth_data);  size = sizeof auth_data.from;  if (getpeername (infd, (struct sockaddr *) &auth_data.from, &size) < 0)    {      syslog (LOG_ERR, "Can't get peer name of remote host: %m");      fatal (outfd, "Can't get peer name of remote host", 1);    }  syslog (LOG_INFO, "Connect from %s:%d",	  inet_ntoa (auth_data.from.sin_addr),	  ntohs (auth_data.from.sin_port));  true = 1;  if (keepalive      && setsockopt (infd, SOL_SOCKET, SO_KEEPALIVE, &true, sizeof true) < 0)    syslog (LOG_WARNING, "setsockopt (SO_KEEPALIVE): %m");#if defined (IP_TOS) && defined (IPPROTO_IP) && defined (IPTOS_LOWDELAY)  true = IPTOS_LOWDELAY;  if (setsockopt (infd, IPPROTO_IP, IP_TOS, (char *) &true, sizeof true) < 0)    syslog (LOG_WARNING, "setsockopt (IP_TOS): %m");#endif  alarm (60);			/* Wait at most 60 seconds. FIXME: configurable? */  /* Read the null byte */  if (read (infd, &c, 1) != 1 || c != 0)    {      syslog (LOG_CRIT, "protocol error: expected 0 byte");      exit (1);    }  alarm (0);  authenticated = rlogind_auth (infd, &auth_data);  pid = forkpty (&master, line, NULL, &win);  if (pid < 0)    {      if (errno == ENOENT)	{	  syslog (LOG_ERR, "Out of ptys");	  fatal (infd, "Out of ptys", 0);	}      else	{	  syslog (LOG_ERR, "forkpty: %m");	  fatal (infd, "Forkpty", 1);	}    }  if (pid == 0)    {      /* Child */      if (infd > 2)	close (infd);      setup_tty (0, &auth_data);      setup_utmp (line);      exec_login (authenticated, &auth_data);      fatal (infd, "can't execute login", 1);    }  /* Parent */  true = 1;  IF_NOT_ENCRYPT (ioctl (infd, FIONBIO, &true));  ioctl (master, FIONBIO, &true);  ioctl (master, TIOCPKT, &true);  netf = infd;			/* Needed for cleanup() */  signal (SIGCHLD, cleanup);  protocol (infd, master, &auth_data);  signal (SIGCHLD, SIG_IGN);  cleanup (0);#ifdef SHISHI  if (kerberos)    {      int             i;      shishi_done (auth_data.h);#ifdef ENCRYPTION      if (encrypt_io)	{	  shishi_key_done (auth_data.enckey);	  for (i = 0; i < 2; i++)	    {	      shishi_crypto_close (auth_data.ivtab[i]->ctx);	      free (auth_data.ivtab[i]->iv);	    }	}#endif    }#endif  return 0;}intdo_rlogin (int infd, struct auth_data *ap){  struct passwd  *pwd;  int             rc;  getstr (infd, &ap->rusername, NULL);  getstr (infd, &ap->lusername, NULL);  getstr (infd, &ap->term, "TERM=");  pwd = getpwnam (ap->lusername);  if (pwd == NULL)    {      syslog (LOG_ERR, "no passwd entry for %s", ap->lusername);      fatal (infd, "Permission denied", 0);    }  if (!allow_root && pwd->pw_uid == 0)    {      syslog (LOG_ERR, "root logins not permitted");      fatal (infd, "Permission denied", 0);    }  rc = iruserok (ap->from.sin_addr.s_addr, 0, ap->rusername, ap->lusername);  if (rc)    syslog (LOG_ERR, "iruserok failed: rusername=%s, lusername=%s",	    ap->rusername, ap->lusername);  return rc;}#if defined(KERBEROS) || defined(SHISHI)intdo_krb_login (int infd, struct auth_data *ap, const char **err_msg){  int             rc;  err_msg = NULL;#if defined(KRB5)  if (kerberos == AUTH_KERBEROS_5)    rc = do_krb5_login (infd, ap, err_msg);  else#elif defined(SHISHI)  if (kerberos == AUTH_KERBEROS_SHISHI)    rc = do_shishi_login (infd, ap, err_msg);  else#else  rc = do_krb4_login (infd, ap, err_msg);#endif  if (rc && !err_msg)    *err_msg = kerberos_error_string (rc);  return rc;}#ifdef KRB4intdo_krb4_login (int infd, struct auth_data *ap, const char **err_msg){  int             rc;  char            instance[INST_SZ], version[VERSION_SZ];  long            authopts = 0L;	/* !mutual */  struct sockaddr_in faddr;  u_char          auth_buf[sizeof (AUTH_DAT)];  u_char          tick_buf[sizeof (KTEXT_ST)];  Key_schedule    schedule;  AUTH_DAT       *kdata;  KTEXT           ticket;  struct passwd  *pwd;  kdata = (AUTH_DAT *) auth_buf;  ticket = (KTEXT) tick_buf;  instance[0] = '*';  instance[1] = '\0';#ifdef ENCRYPTION  if (encrypt_io)    {      rc = sizeof faddr;      if (getsockname (0, (struct sockaddr *) &faddr, &rc))	{	  *err_msg = "getsockname failed";	  syslog (LOG_ERR, "getsockname failed: %m");	  return 1;	}      authopts = KOPT_DO_MUTUAL;      rc = krb_recvauth (authopts, 0,			 ticket, "rcmd",			 instance, &ap->from, &faddr,			 kdata, "", schedule, version);      des_set_key (kdata->session, schedule);    }  else#endif    rc = krb_recvauth (authopts, 0,		       ticket, "rcmd",		       instance, &ap->from, NULL, kdata, "", NULL, version);  if (rc != KSUCCESS)    return 1;  getstr (infd, &ap->lusername, NULL);  /* get the "cmd" in the rcmd protocol */  getstr (infd, &ap->term, "TERM=");  pwd = getpwnam (ap->lusername);  if (pwd == NULL)    {      *err_msg = "getpwnam failed";      syslog (LOG_ERR, "getpwnam failed: %m");      return 1;    }  /* returns nonzero for no access */  if (kuserok (kdata, ap->lusername) != 0)    return 1;  if (pwd->pw_uid == 0)    syslog (LOG_INFO | LOG_AUTH,	    "ROOT Kerberos login from %s.%s@%s on %s\n",	    kdata->pname, kdata->pinst, kdata->prealm, ap->hostname);  else    syslog (LOG_INFO | LOG_AUTH,	    "%s Kerberos login from %s.%s@%s on %s\n",	    pwd->pw_name,	    kdata->pname, kdata->pinst, kdata->prealm, ap->hostname);  return 0;}#endif#ifdef KRB5intdo_krb5_login (int infd, struct auth_data *ap, const char **err_msg){  krb5_auth_context auth_ctx = NULL;  krb5_error_code status;  krb5_data       inbuf;  krb5_data       version;  krb5_authenticator *authenticator;  krb5_rcache     rcache;  krb5_keyblock  *key;  krb5_ticket    *ticket;  struct sockaddr_in laddr;  int             len;  struct passwd  *pwd;  char           *name;  if (status = krb5_init_context (&ap->context))    {      syslog (LOG_ERR, "Error initializing krb5: %s", error_message (status));      return status;    }  if ((status = krb5_auth_con_init (ap->context, &auth_ctx))      || (status = krb5_auth_con_genaddrs (ap->context, auth_ctx, infd,					   KRB5_AUTH_CONTEXT_GENERATE_REMOTE_FULL_ADDR))      || (status = krb5_auth_con_getrcache (ap->context, auth_ctx, &rcache)))    return status;  if (!rcache)    {      krb5_principal  server;      status = krb5_sname_to_principal (ap->context, 0, 0, KRB5_NT_SRV_HST,					&server);      if (status)	return status;      status = krb5_get_server_rcache (ap->context,				       krb5_princ_component (ap->context,							     server, 0),				       &rcache);      krb5_free_principal (ap->context, server);      if (status)	return status;      status = krb5_auth_con_setrcache (ap->context, auth_ctx, rcache);      if (status)	return status;    }  len = sizeof (laddr);  if (getsockname (infd, (struct sockaddr *) &laddr, &len))    return errno;  status = krb5_recvauth (ap->context, &auth_ctx, &infd, NULL, 0,			  0, ap->keytab, &ticket);  if (status)    return status;  if ((status = krb5_auth_con_getauthenticator (ap->context, auth_ctx,						&authenticator)))    return status;  getstr (infd, &ap->lusername, NULL);  getstr (infd, &ap->term, "TERM=");  pwd = getpwnam (ap->lusername);  if (pwd == NULL)    {      *err_msg = "getpwnam failed";      syslog (LOG_ERR, "getpwnam failed: %m");      return 1;    }  getstr (infd, &ap->rusername, NULL);  if ((status = krb5_copy_principal (ap->context,				     ticket->enc_part2->client, &ap->client)))    return status;  /*OK:: */  if (ap->client && !krb5_kuserok (ap->context, ap->client, ap->lusername))    return 1;  krb5_unparse_name (ap->context, ap->client, &name);  syslog (LOG_INFO | LOG_AUTH,	  "%sKerberos V login from %s on %s\n",	  (pwd->pw_uid == 0) ? "ROOT " : "", name, ap->hostname);  free (name);  return 0;}#endif#ifdef SHISHIintdo_shishi_login (int infd, struct auth_data *ad, const char **err_msg){  int             rc;  int             error = 0;  int             keylen, keytype;  struct passwd  *pwd = NULL;  int             cksumtype, cksumlen = 30;  char           *cksum;  char           *compcksum;  size_t          compcksumlen;  char            cksumdata[100];  struct sockaddr_in sock;  size_t          socklen = sizeof (struct sockaddr_in);#ifdef ENCRYPTION

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -