summaryrefslogtreecommitdiff
path: root/security/ssh/patches/patch-at
blob: aa9b64f3701e5fcd7dabb46b056b8c8495d596e4 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
$NetBSD: patch-at,v 1.2 2000/04/18 19:02:21 thorpej Exp $

--- auth-passwd.c.orig	Wed May 12 04:19:23 1999
+++ auth-passwd.c	Tue Apr 18 11:48:03 2000
@@ -301,29 +301,25 @@
 static int securid_initialized = 0;
 #endif /* HAVE_SECURID */
 
-#ifdef KERBEROS
-#if defined(KRB5)
+#ifdef KRB5
 #include <krb5.h>
 extern  krb5_context ssh_context;
 extern  krb5_auth_context auth_context;
-#else
-#include <krb.h>
 #endif /* KRB5 */
-#endif /* KERBEROS */
 
-#ifdef AFS
-#include <afs/param.h>
-#include <afs/kautils.h>
-#endif /* AFS */
+#ifdef KRB4
+#include <sys/param.h>
+#include <krb.h>
+#endif /* KRB4 */
 
-#if defined(KERBEROS) || defined(AFS_KERBEROS)
+#if defined(KRB4) || defined(KRB5)
 extern char *ticket;
-#endif /* KERBEROS || AFS_KERBEROS */
+#endif /* KRB4 || KRB5 */
 
 /* Tries to authenticate the user using password.  Returns true if
    authentication succeeds. */
 
-#if defined(KERBEROS) && defined(KRB5)
+#ifdef KRB5
 /*
  * This routine with some modification is from the MIT V5B6 appl/bsd/login.c
  *
@@ -479,16 +475,16 @@
                                      0 };
 #endif
 krb5_preauthtype * preauth = preauth_list;
-#endif /* KERBEROS */
+#endif /* KRB5 */
 
 /* Tries to authenticate the user using password.  Returns true if
    authentication succeeds. */
-#ifdef KERBEROS
+#ifdef KRB5
 int auth_password(const char *server_user, const char *password,
                   krb5_principal client)
-#else  /* KERBEROS */
+#else  /* KRB5 */
 int auth_password(const char *server_user, const char *password)
-#endif /* KERBEROS */
+#endif /* KRB5 */
 {
 #if defined(_AIX) && defined(HAVE_AUTHENTICATE)
   char *message;
@@ -505,7 +501,7 @@
     }
 #else /* _AIX41 && HAVE_AUTHENTICATE */
 
-#ifdef KERBEROS
+#ifdef KRB5
   krb5_error_code problem;
   int krb5_options = KDC_OPT_RENEWABLE | KDC_OPT_FORWARDABLE;
   krb5_deltat rlife = 0;
@@ -515,7 +511,7 @@
   krb5_ccache ccache;
   char ccname[80];
   int results;
-#endif  /* KERBEROS */
+#endif  /* KRB5 */
   extern ServerOptions options;
   extern char *crypt(const char *key, const char *salt);
   struct passwd *pw;
@@ -537,10 +533,9 @@
   saved_pw_name = xstrdup(pw->pw_name);
   saved_pw_passwd = xstrdup(pw->pw_passwd);
   
-#if defined(KERBEROS)
-  if (options.kerberos_authentication)
-    {
 #if defined(KRB5)
+  if (options.kerberos_authentication && client != NULL)
+    {
       snprintf(ccname, sizeof(ccname), "FILE:/tmp/krb5cc_l%d", getpid());
       
       if (problem = krb5_cc_resolve(ssh_context, ccname, &ccache))
@@ -658,9 +653,96 @@
               return 0;
             }
         }
+    }
 #endif /* KRB5 */
+#ifdef KRB4
+  if (options.kerberos_authentication)
+    {
+      AUTH_DAT adata;
+      KTEXT_ST tkt;
+      struct hostent *hp;
+      unsigned long faddr;
+      char localhost[MAXHOSTNAMELEN];	/* local host name */
+      char phost[INST_SZ];		/* host instance */
+      char realm[REALM_SZ];		/* local Kerberos realm */
+      int r;
+      
+      /* Try Kerberos password authentication only for non-root
+	 users and only if Kerberos is installed. */
+      if (pw->pw_uid != 0 && krb_get_lrealm(realm, 0) == KSUCCESS) {
+
+	/* Set up our ticket file. */
+	if (!ssh_tf_init(pw->pw_uid)) {
+	  log_msg("Couldn't initialize Kerberos ticket file for %s!",
+		  server_user);
+	  goto kerberos_auth_failure;
+	}
+	/* Try to get TGT using our password. */
+        if ((r = krb_get_pw_in_tkt((char *)server_user, "", realm, "krbtgt",
+             realm, DEFAULT_TKT_LIFE, (char *)password)) != INTK_OK) {
+	  packet_send_debug("Kerberos V4 password authentication for %s "
+			    "failed: %s", server_user, krb_err_txt[r]);
+	  goto kerberos_auth_failure;
+	}
+	/* Successful authentication. */
+	chown(ticket, pw->pw_uid, pw->pw_gid);
+	
+	(void) gethostname(localhost, sizeof(localhost));
+	(void) strncpy(phost, (char *)krb_get_phost(localhost), INST_SZ);
+	phost[INST_SZ-1] = 0;
+	
+	/* Now that we have a TGT, try to get a local "rcmd" ticket to
+	   ensure that we are not talking to a bogus Kerberos server. */
+	r = krb_mk_req(&tkt, KRB4_SERVICE_NAME, phost, realm, 33);
+
+	if (r == KSUCCESS) {
+	  if (!(hp = gethostbyname(localhost))) {
+	    log_msg("Couldn't get local host address!");
+	    goto kerberos_auth_failure;
+	  }
+	  memmove((void *)&faddr, (void *)hp->h_addr, sizeof(faddr));
+
+	  /* Verify our "rcmd" ticket. */
+	  r = krb_rd_req(&tkt, KRB4_SERVICE_NAME, phost, faddr, &adata, "");
+	  if (r == RD_AP_UNDEC) {
+	    /* Probably didn't have a srvtab on localhost. Allow login. */
+	    log_msg("Kerberos V4 TGT for %s unverifiable, no srvtab? "
+		    "krb_rd_req: %s", server_user, krb_err_txt[r]);
+	  }
+	  else if (r != KSUCCESS) {
+	    log_msg("Kerberos V4 %s ticket unverifiable: %s",
+		    KRB4_SERVICE_NAME, krb_err_txt[r]);
+	    goto kerberos_auth_failure;
+	  }
+	}
+	else if (r == KDC_PR_UNKNOWN) {
+	  /* Allow login if no rcmd service exists, but log the error. */
+	  log_msg("Kerberos V4 TGT for %s unverifiable: %s; %s.%s "
+		  "not registered, or srvtab is wrong?", server_user,
+		  krb_err_txt[r], KRB4_SERVICE_NAME, phost);
+	}
+	else {
+	  /* TGT is bad, forget it. Possibly spoofed. */
+	  packet_send_debug("WARNING: Kerberos V4 TGT possibly spoofed for"
+			    "%s: %s", server_user, krb_err_txt[r]);
+	  goto kerberos_auth_failure;
+	}
+	
+	/* Authentication succeeded. */
+	return 1;
+	
+      kerberos_auth_failure:
+	(void) dest_tkt();
+	xfree(ticket);
+	ticket = NULL;
+	if (!options.kerberos_or_local_passwd ) return 0;
+      }
+      else /* Logging in as root or no local Kerberos realm. */
+	packet_send_debug("Unable to authenticate to Kerberos.");
+      
+      /* Fall back to ordinary passwd authentication. */
     }
-#endif /* KERBEROS */
+#endif /* KRB4 */
   
 #ifdef HAVE_SECURID
   /* Support for Security Dynamics SecurId card.