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 */ |
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'}, |
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'}, |
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; |
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)); |
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) |
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 */ |
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 |
} |
} |
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 |
} |
} |
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 |
} |
} |
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 |
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 |
|
|
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 |
|
|
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, |
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 |
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 |
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 |
|
} |