/[inetutils]/inetutils/rlogind/rlogind.c
ViewVC logotype

Diff of /inetutils/rlogind/rlogind.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 1.29 by gray, Sat Nov 3 23:09:28 2001 UTC revision 1.30 by gray, Sun Apr 7 15:29:12 2002 UTC
# Line 102  Line 102 
102  #define TTYDEF_LFLAG    (ECHO | ICANON | ISIG | IEXTEN | ECHOE|ECHOKE|ECHOCTL)  #define TTYDEF_LFLAG    (ECHO | ICANON | ISIG | IEXTEN | ECHOE|ECHOKE|ECHOCTL)
103  #endif  #endif
104    
105  #ifdef  KERBEROS  #define AUTH_KERBEROS_4 4
106  # include <kerberosIV/des.h>  #define AUTH_KERBEROS_5 5
107  # include <kerberosIV/krb.h>  
108    #ifdef KERBEROS
109  # define        SECURE_MESSAGE "This rlogin session is using DES encryption for all transmissions.\r\n"  # define        SECURE_MESSAGE "This rlogin session is using DES encryption for all transmissions.\r\n"
110    # ifdef KERBEROS_IV
111    #  include <kerberosIV/des.h>
112    #  include <kerberosIV/krb.h>
113    #  define kerberos_error_string(c) krb_err_txt[c]
114    #  define AUTH_KERBEROS_DEFAULT AUTH_KERBEROS_4
115    # elif defined(KERBEROS_V)
116    #  include <krb5.h>
117    #  include <kerberosIV/krb.h>
118    #  define kerberos_error_string(c) error_message (c)
119    #  define AUTH_KERBEROS_DEFAULT AUTH_KERBEROS_5
120    # endif
121  #endif /* KERBEROS */  #endif /* KERBEROS */
122    
123  #define ENVSIZE (sizeof("TERM=")-1)     /* skip null for concatenation */  #define ENVSIZE (sizeof("TERM=")-1)     /* skip null for concatenation */
# Line 127  struct auth_data Line 139  struct auth_data
139    char *rusername;    char *rusername;
140    char *term;    char *term;
141    char *env[2];    char *env[2];
142    #ifdef KERBEROS
143    #ifdef KERBEROS_V
144      int kerberos_version;
145      krb5_principal client;
146      krb5_context context;
147      krb5_ccache ccache;
148      krb5_keytab keytab;
149    #endif
150    #endif
151  };  };
152    
153  static const char *short_options = "aD::d::hkL:lnp:orxV";  static const char *short_options = "aD::d::hk::L:lnp:orxV";
154  static struct option long_options[] =  static struct option long_options[] =
155  {  {
156    {"allow-root", no_argument, 0, 'o'},    {"allow-root", no_argument, 0, 'o'},
# Line 138  static struct option long_options[] = Line 159  static struct option long_options[] =
159    {"no-rhosts", no_argument, 0, 'l'},    {"no-rhosts", no_argument, 0, 'l'},
160    {"no-keepalive", no_argument, 0, 'n'},    {"no-keepalive", no_argument, 0, 'n'},
161    {"local-domain", required_argument, 0, 'L'},    {"local-domain", required_argument, 0, 'L'},
162    {"kerberos", no_argument, 0, 'k'},    {"kerberos", optional_argument, 0, 'k'},
163    {"encrypt", no_argument, 0, 'x'},    {"encrypt", no_argument, 0, 'x'},
164    {"debug", optional_argument, 0, 'D'},    {"debug", optional_argument, 0, 'D'},
165    {"help", no_argument, 0, 'h'},    {"help", no_argument, 0, 'h'},
# Line 154  int keepalive = 1; Line 175  int keepalive = 1;
175  #ifdef KERBEROS  #ifdef KERBEROS
176  int kerberos = 0;  int kerberos = 0;
177  #ifdef ENCRYPTION  #ifdef ENCRYPTION
178  int encrypt = 0;  int encrypt_io = 0;
179  #endif /* ENCRYPTION */  #endif /* ENCRYPTION */
180  #endif /* KERBEROS */  #endif /* KERBEROS */
181  int reverse_required = 0;  int reverse_required = 0;
# Line 177  void setup_tty __P ((int fd, struct auth Line 198  void setup_tty __P ((int fd, struct auth
198  void exec_login __P ((int authenticated, struct auth_data *ap));  void exec_login __P ((int authenticated, struct auth_data *ap));
199  int rlogind_mainloop __P ((int infd, int outfd));  int rlogind_mainloop __P ((int infd, int outfd));
200  int do_rlogin __P ((int infd, struct auth_data *ap));  int do_rlogin __P ((int infd, struct auth_data *ap));
201  int do_krb_login __P ((int infd, struct auth_data *ap));  int do_krb_login __P ((int infd, struct auth_data *ap, const char **msg));
202  void getstr __P ((int infd, char **ptr, const char *prefix));  void getstr __P ((int infd, char **ptr, const char *prefix));
203  void protocol __P ((int f, int p));  void protocol __P ((int f, int p));
204  int control __P ((int pty, char *cp, size_t n));  int control __P ((int pty, char *cp, size_t n));
# Line 201  rlogind_sigchld (int sig) Line 222  rlogind_sigchld (int sig)
222  #define MODE_DAEMON 1  #define MODE_DAEMON 1
223    
224  #if defined(KERBEROS) && defined(ENCRYPTION)  #if defined(KERBEROS) && defined(ENCRYPTION)
225  # define IF_ENCRYPT(stmt) if (encrypt) stmt  # define ENCRYPT_IO encrypt_io
226  # define IF_NOT_ENCRYPT(stmt) if (!encrypt) stmt  # define IF_ENCRYPT(stmt) if (encrypt_io) stmt
227    # define IF_NOT_ENCRYPT(stmt) if (!encrypt_io) stmt
228  # define ENC_READ(c, fd, buf, size) \  # define ENC_READ(c, fd, buf, size) \
229   if (encrypt) \   if (encrypt_io) \
230       c = des_read(fd, buf, size); \       c = des_read(fd, buf, size); \
231   else \   else \
232       c = read(fd, buf, size);       c = read(fd, buf, size);
233  # define ENC_WRITE(c, fd, buf, size) \  # define ENC_WRITE(c, fd, buf, size) \
234   if (encrypt) \   if (encrypt_io) \
235       c = des_write(fd, buf, size); \       c = des_write(fd, buf, size); \
236   else \   else \
237       c = write(fd, buf, size);       c = write(fd, buf, size);
238  #else  #else
239    # define ENCRYPT_IO 0
240  # define IF_ENCRYPT(stmt)  # define IF_ENCRYPT(stmt)
241  # define IF_NOT_ENCRYPT(stmt) stmt  # define IF_NOT_ENCRYPT(stmt) stmt
242  # define ENC_READ(c, fd, buf, size) c = read (fd, buf, size)  # define ENC_READ(c, fd, buf, size) c = read (fd, buf, size)
# Line 264  main (int argc, char *argv[]) Line 287  main (int argc, char *argv[])
287    
288  #ifdef KERBEROS  #ifdef KERBEROS
289          case 'k':          case 'k':
290            kerberos = 1;            if (optarg)
291                {
292                  if (*optarg == '4')
293                    kerberos = AUTH_KERBEROS_4;
294                  else if (*optarg == '5')
295                    kerberos = AUTH_KERBEROS_5;
296                }
297              else
298                kerberos = AUTH_KERBEROS_DEFAULT;
299            break;            break;
300    
301  # ifdef ENCRYPTION  # ifdef ENCRYPTION
302          case 'x':          case 'x':
303            encrypt = 1;            encrypt_io = 1;
304            break;            break;
305  # endif /* ENCRYPTION */  # endif /* ENCRYPTION */
306  #endif /* KERBEROS */  #endif /* KERBEROS */
# Line 479  rlogind_auth (int fd, struct auth_data * Line 510  rlogind_auth (int fd, struct auth_data *
510  #ifdef  KERBEROS  #ifdef  KERBEROS
511    if (kerberos)    if (kerberos)
512      {      {
513        int rc = do_krb_login (infd, ap);        const char *err_msg;
514        if (rc == 0)        int c = 0;
515          if (do_krb_login (fd, ap, &err_msg) == 0)
516          authenticated++;          authenticated++;
517        else if (rc > 0)        else
518          fatal (fd, krb_err_txt[rc], 0);          fatal (fd, err_msg, 0);
519        write (fd, &c, 1);        write (fd, &c, 1);
520        confirmed = 1;            /* we sent the null! */        confirmed = 1;            /* we sent the null! */
521      }      }
# Line 596  exec_login(int authenticated, struct aut Line 628  exec_login(int authenticated, struct aut
628                ap->lusername, NULL, ap->env);                ap->lusername, NULL, ap->env);
629  #else  #else
630        execle (path_login, "login", "-p",        execle (path_login, "login", "-p",
631                "-h", ap->hostname, "-f", "--",                "-h", ap->hostname, "-f",
632                ap->lusername, NULL, ap->env);                ap->lusername, NULL, ap->env);
633  #endif  #endif
634      }      }
# Line 608  exec_login(int authenticated, struct aut Line 640  exec_login(int authenticated, struct aut
640                ap->lusername, NULL, ap->env);                ap->lusername, NULL, ap->env);
641  #else  #else
642        execle (path_login, "login", "-p",        execle (path_login, "login", "-p",
643                "-h", ap->hostname, "--",                "-h", ap->hostname,
644                ap->lusername, NULL, ap->env);                ap->lusername, NULL, ap->env);
645  #endif  #endif
646      }      }
# Line 634  rlogind_mainloop (int infd, int outfd) Line 666  rlogind_mainloop (int infd, int outfd)
666        fatal (outfd, "Can't get peer name of remote host", 1);        fatal (outfd, "Can't get peer name of remote host", 1);
667      }      }
668    
669    syslog (LOG_INFO, "Connect from %s", inet_ntoa(auth_data.from.sin_addr));    syslog (LOG_INFO, "Connect from %s:%d",
670              inet_ntoa(auth_data.from.sin_addr), ntohs(auth_data.from.sin_port));
671    
672    true = 1;    true = 1;
673    if (keepalive    if (keepalive
# Line 735  do_rlogin(int infd, struct auth_data *ap Line 768  do_rlogin(int infd, struct auth_data *ap
768    
769  #ifdef KERBEROS  #ifdef KERBEROS
770  int  int
771  do_krb_login (int infd, struct auth_data *ap)  do_krb_login (int infd, struct auth_data *ap, const char **err_msg)
772  {  {
773    int rc;    int rc;
774    char instance[INST_SZ], version[VERSION_SIZE];  
775      err_msg = NULL;
776    #ifdef KERBEROS_V
777      if (kerberos == AUTH_KERBEROS_5)
778        rc = do_krb5_login (infd, ap, err_msg);
779      else
780    #endif
781        rc = do_krb4_login (infd, ap, err_msg);
782      
783      if (rc && !err_msg)
784        *err_msg = kerberos_error_string (rc);
785      return rc;
786    }
787    
788    int
789    do_krb4_login (int infd, struct auth_data *ap, const char **err_msg)
790    {
791      int rc;
792      char instance[INST_SZ], version[VERSION_SZ];
793    long authopts = 0L;           /* !mutual */    long authopts = 0L;           /* !mutual */
794    struct sockaddr_in faddr;    struct sockaddr_in faddr;
795    u_char auth_buf[sizeof (AUTH_DAT)];    u_char auth_buf[sizeof (AUTH_DAT)];
796    u_char tick_buf[sizeof (KTEXT_ST)];    u_char tick_buf[sizeof (KTEXT_ST)];
797    Key_schedule schedule;    Key_schedule schedule;
798    AUTH_DAT *kdata;    AUTH_DAT *kdata;
799      KTEXT ticket;
800      struct passwd *pwd;
801      
802    kdata = (AUTH_DAT *) auth_buf;    kdata = (AUTH_DAT *) auth_buf;
803    ticket = (KTEXT) tick_buf;    ticket = (KTEXT) tick_buf;
804    
# Line 753  do_krb_login (int infd, struct auth_data Line 806  do_krb_login (int infd, struct auth_data
806    instance[1] = '\0';    instance[1] = '\0';
807    
808  #ifdef ENCRYPTION  #ifdef ENCRYPTION
809    if (encrypt)    if (encrypt_io)
810      {      {
811        rc = sizeof faddr;        rc = sizeof faddr;
812        if (getsockname (0, (struct sockaddr *) &faddr, &rc))        if (getsockname (0, (struct sockaddr *) &faddr, &rc))
813          return -1;          {
814              *err_msg = "getsockname failed";
815              syslog (LOG_ERR, "getsockname failed: %m");
816              return 1;
817            }
818        authopts = KOPT_DO_MUTUAL;        authopts = KOPT_DO_MUTUAL;
819        rc = krb_recvauth (authopts, 0,        rc = krb_recvauth (authopts, 0,
820                           ticket, "rcmd",                           ticket, "rcmd",
821                           instance, ap->from, &faddr,                           instance, &ap->from, &faddr,
822                           kdata, "", schedule, version);                           kdata, "", schedule, version);
823        des_set_key (kdata->session, schedule);        des_set_key (kdata->session, schedule);
824    
# Line 770  do_krb_login (int infd, struct auth_data Line 827  do_krb_login (int infd, struct auth_data
827  #endif  #endif
828      rc = krb_recvauth (authopts, 0,      rc = krb_recvauth (authopts, 0,
829                         ticket, "rcmd",                         ticket, "rcmd",
830                         instance, ap->from, NULL,                         instance, &ap->from, NULL,
831                         kdata, "", NULL, version);                         kdata, "", NULL, version);
832    
833    if (rc != KSUCCESS)    if (rc != KSUCCESS)
834      return rc;      return 1;
835      
836    getstr (infd, &ap->lusername, NULL);    getstr (infd, &ap->lusername, NULL);
837    /* get the "cmd" in the rcmd protocol */    /* get the "cmd" in the rcmd protocol */
838    getstr (infd, &ap->term, "TERM=");    getstr (infd, &ap->term, "TERM=");
839    
840    pwd = getpwnam (ap->lusername);    pwd = getpwnam (ap->lusername);
841    if (pwd == NULL)    if (pwd == NULL)
842      return -1;      {
843          *err_msg = "getpwnam failed";
844          syslog (LOG_ERR, "getpwnam failed: %m");
845          return 1;
846        }
847    /* returns nonzero for no access */    /* returns nonzero for no access */
848    if (kuserok (kdata, ap->lusername) != 0)    if (kuserok (kdata, ap->lusername) != 0)
849      return -1;      return 1;
850    
851    if (pwd->pw_uid == 0)    if (pwd->pw_uid == 0)
852      syslog (LOG_INFO | LOG_AUTH,      syslog (LOG_INFO | LOG_AUTH,
# Line 800  do_krb_login (int infd, struct auth_data Line 860  do_krb_login (int infd, struct auth_data
860    
861    return 0;    return 0;
862  }  }
863    
864    #ifdef KERBEROS_V
865    int
866    do_krb5_login (int infd, struct auth_data *ap, const char **err_msg)
867    {
868      krb5_auth_context auth_ctx = NULL;
869      krb5_error_code status;
870      krb5_data inbuf;
871      krb5_data version;
872      krb5_authenticator *authenticator;
873      krb5_rcache rcache;
874      krb5_keyblock *key;
875      krb5_ticket *ticket;
876      struct sockaddr_in laddr;
877      int len;
878      struct passwd *pwd;
879      char *name;
880    
881      if (status = krb5_init_context (&ap->context))
882        {
883          syslog (LOG_ERR, "Error initializing krb5: %s",
884                  error_message (status));
885          return status;
886        }
887    
888      if ((status = krb5_auth_con_init (ap->context, &auth_ctx))
889          || (status = krb5_auth_con_genaddrs (ap->context, auth_ctx, infd,
890                                 KRB5_AUTH_CONTEXT_GENERATE_REMOTE_FULL_ADDR))
891          || (status = krb5_auth_con_getrcache (ap->context, auth_ctx, &rcache)))
892        return status;
893    
894      if (!rcache)
895        {
896          krb5_principal server;
897          status = krb5_sname_to_principal (ap->context, 0, 0, KRB5_NT_SRV_HST,
898                                            &server);
899          if (status)
900            return status;
901          
902          status =  krb5_get_server_rcache (ap->context,
903                                krb5_princ_component (ap->context, server, 0),
904                                &rcache);
905          krb5_free_principal(ap->context, server);
906          
907          if (status)
908            return status;
909          
910          status = krb5_auth_con_setrcache (ap->context, auth_ctx, rcache);
911          if (status)
912            return status;
913        }
914    
915      len = sizeof (laddr);
916      if (getsockname (infd, (struct sockaddr *)&laddr, &len))
917        return errno;
918    
919      status = krb5_recvauth (ap->context, &auth_ctx, &infd, NULL, 0,
920                              0, ap->keytab, &ticket);
921      if (status)
922        return status;
923    
924      if ((status = krb5_auth_con_getauthenticator (ap->context, auth_ctx,
925                                                    &authenticator)))
926        return status;
927      
928      getstr (infd, &ap->lusername, NULL);
929      getstr (infd, &ap->term, "TERM=");
930      
931      pwd = getpwnam (ap->lusername);
932      if (pwd == NULL)
933        {
934          *err_msg = "getpwnam failed";
935          syslog (LOG_ERR, "getpwnam failed: %m");
936          return 1;
937        }
938      
939      getstr (infd, &ap->rusername, NULL);
940    
941      if ((status = krb5_copy_principal(ap->context,
942                                        ticket->enc_part2->client,
943                                        &ap->client)))
944        return status;
945          
946      /*OK::*/
947      if (ap->client && !krb5_kuserok (ap->context, ap->client, ap->lusername))
948        return 1;
949    
950      krb5_unparse_name (ap->context, ap->client, &name);
951      
952      syslog (LOG_INFO | LOG_AUTH,
953              "%sKerberos V login from %s on %s\n",
954              (pwd->pw_uid == 0) ? "ROOT " : "",
955              name, ap->hostname);
956      free (name);
957      
958      return 0;
959    }
960    
961    #endif
962  #endif  #endif
963    
964  #define BUFFER_SIZE 128  #define BUFFER_SIZE 128
# Line 868  protocol (int f, int p) Line 1027  protocol (int f, int p)
1027    int pcc = 0, fcc = 0;    int pcc = 0, fcc = 0;
1028    int cc, nfd, n;    int cc, nfd, n;
1029    char cntl;    char cntl;
1030    #ifdef TIOCPKT
1031      int tiocpkt_on = 0;
1032    #endif
1033    
1034    /*    /*
1035     * Must ignore SIGTTOU, otherwise we'll stop     * Must ignore SIGTTOU, otherwise we'll stop
# Line 1163  usage() Line 1325  usage()
1325           "Send bug reports to %s\n",           "Send bug reports to %s\n",
1326           usage_str, inetutils_bugaddr);           usage_str, inetutils_bugaddr);
1327  }  }
1328    
1329    int volatile _st;
1330    stop()
1331    {
1332            for (_st=0; !_st;)
1333                    _st=_st;
1334    }

Legend:
Removed from v.1.29  
changed lines
  Added in v.1.30

savannah-hackers-public@gnu.org
ViewVC Help
Powered by ViewVC 1.1.26