Revert "Revert "oran-shell-release: release image for F""
[pti/rtp.git] / meta-starlingx / meta-stx-distro / recipes-security / gssproxy / files / Allow-connection-to-self-when-impersonator-set.patch
1 From 0e04be2c1398dac40c50910a59157eed0ad5a7e4 Mon Sep 17 00:00:00 2001
2 From: Simo Sorce <simo@redhat.com>
3 Date: Tue, 14 Mar 2017 10:43:17 -0400
4 Subject: [PATCH] Allow connection to self when impersonator set
5
6 If the target of a context establishment is the impersonator itself,
7 then allow it. This kind of context establishment is used by tools like
8 mod_auth_gssapi to be able to inspect the ticket just obtained via
9 impersonation and it is basically a noop as the acceptor and the
10 impersonator are the same entitiy.
11
12 Signed-off-by: Simo Sorce <simo@redhat.com>
13 Reviewed-by: Robbie Harwood <rharwood@redhat.com>
14 Merges: #172
15 (cherry picked from commit eada55e831d12b42d3be3a555ff4e133bed7f594)
16 ---
17  proxy/src/gp_creds.c                | 57 +++++++++++++++++++++++++----
18  proxy/src/gp_rpc_creds.h            |  3 +-
19  proxy/src/gp_rpc_init_sec_context.c |  2 +-
20  proxy/tests/t_impersonate.py        | 35 +++++++++++++-----
21  4 files changed, 78 insertions(+), 19 deletions(-)
22
23 diff --git a/proxy/src/gp_creds.c b/proxy/src/gp_creds.c
24 index 95a1c48..7d89b06 100644
25 --- a/proxy/src/gp_creds.c
26 +++ b/proxy/src/gp_creds.c
27 @@ -883,7 +883,8 @@ static uint32_t get_impersonator_name(uint32_t *min, gss_cred_id_t cred,
28          }
29      } else if (ret_maj == GSS_S_UNAVAILABLE) {
30          /* Not supported by krb5 library yet, fallback to raw krb5 calls */
31 -        /* TODO: Remove once we set a required dependency on MIT 1.15+ */
32 +        /* TODO: Remove once we set a minimum required dependency on a
33 +         * release that supports this call */
34          ret_maj = get_impersonator_fallback(&ret_min, cred, impersonator);
35          if (ret_maj == GSS_S_FAILURE) {
36              if (ret_min == KRB5_CC_NOTFOUND) {
37 @@ -899,9 +900,47 @@ done:
38      return ret_maj;
39  }
40  
41 +static uint32_t check_impersonator_name(uint32_t *min,
42 +                                        gss_name_t target_name,
43 +                                        const char *impersonator)
44 +{
45 +    gss_name_t canon_name = NULL;
46 +    gss_buffer_desc buf;
47 +    uint32_t ret_maj = 0;
48 +    uint32_t ret_min = 0;
49 +    uint32_t discard;
50 +    bool match;
51 +
52 +    ret_maj = gss_canonicalize_name(&discard, target_name, &gp_mech_krb5,
53 +                                    &canon_name);
54 +    if (ret_maj != GSS_S_COMPLETE) {
55 +        *min = ret_min;
56 +        return ret_maj;
57 +    }
58 +
59 +    ret_maj = gss_display_name(&discard, canon_name, &buf, NULL);
60 +    gss_release_name(&discard, &canon_name);
61 +    if (ret_maj != GSS_S_COMPLETE) {
62 +        *min = ret_min;
63 +        return ret_maj;
64 +    }
65 +
66 +    match = (strncmp(impersonator, buf.value, buf.length) == 0) &&
67 +            (strlen(impersonator) == buf.length);
68 +    gss_release_buffer(&discard, &buf);
69 +
70 +    *min = 0;
71 +    if (match) {
72 +        return GSS_S_COMPLETE;
73 +    } else {
74 +        return GSS_S_UNAUTHORIZED;
75 +    }
76 +}
77 +
78  uint32_t gp_cred_allowed(uint32_t *min,
79                           struct gp_call_ctx *gpcall,
80 -                         gss_cred_id_t cred)
81 +                         gss_cred_id_t cred,
82 +                         gss_name_t target_name)
83  {
84      char *impersonator = NULL;
85      uint32_t ret_maj = 0;
86 @@ -924,11 +963,11 @@ uint32_t gp_cred_allowed(uint32_t *min,
87      if (ret_maj) goto done;
88  
89      /* if we find an impersonator entry we bail as that is not authorized,
90 -     * if it were then gpcall->service->allow_const_deleg would have caused
91 -     * the ealier check to return GSS_S_COMPLETE already */
92 +     * *unless* the target is the impersonator itself! If the operation
93 +     * were authorized then gpcall->service->allow_const_deleg would have
94 +     * caused the ealier check to return GSS_S_COMPLETE already */
95      if (impersonator != NULL) {
96 -        ret_min = 0;
97 -        ret_maj = GSS_S_UNAUTHORIZED;
98 +        ret_maj = check_impersonator_name(&ret_min, target_name, impersonator);
99      }
100  
101  done:
102 @@ -937,7 +976,11 @@ done:
103          GPDEBUGN(2, "Unauthorized impersonator credentials detected\n");
104          break;
105      case GSS_S_COMPLETE:
106 -        GPDEBUGN(2, "No impersonator credentials detected\n");
107 +        if (impersonator) {
108 +            GPDEBUGN(2, "Credentials allowed for 'self'\n");
109 +        } else {
110 +            GPDEBUGN(2, "No impersonator credentials detected\n");
111 +        }
112          break;
113      default:
114          GPDEBUG("Failure while checking credentials\n");
115 diff --git a/proxy/src/gp_rpc_creds.h b/proxy/src/gp_rpc_creds.h
116 index 54fe482..c116e53 100644
117 --- a/proxy/src/gp_rpc_creds.h
118 +++ b/proxy/src/gp_rpc_creds.h
119 @@ -34,7 +34,8 @@ uint32_t gp_add_krb5_creds(uint32_t *min,
120  
121  uint32_t gp_cred_allowed(uint32_t *min,
122                           struct gp_call_ctx *gpcall,
123 -                         gss_cred_id_t cred);
124 +                         gss_cred_id_t cred,
125 +                         gss_name_t target_name);
126  
127  void gp_filter_flags(struct gp_call_ctx *gpcall, uint32_t *flags);
128  
129 diff --git a/proxy/src/gp_rpc_init_sec_context.c b/proxy/src/gp_rpc_init_sec_context.c
130 index 767a3ff..413e2ec 100644
131 --- a/proxy/src/gp_rpc_init_sec_context.c
132 +++ b/proxy/src/gp_rpc_init_sec_context.c
133 @@ -108,7 +108,7 @@ int gp_init_sec_context(struct gp_call_ctx *gpcall,
134          }
135      }
136  
137 -    ret_maj = gp_cred_allowed(&ret_min, gpcall, ich);
138 +    ret_maj = gp_cred_allowed(&ret_min, gpcall, ich, target_name);
139      if (ret_maj) {
140          goto done;
141      }
142 diff --git a/proxy/tests/t_impersonate.py b/proxy/tests/t_impersonate.py
143 index 3e25962..29f9a41 100755
144 --- a/proxy/tests/t_impersonate.py
145 +++ b/proxy/tests/t_impersonate.py
146 @@ -34,19 +34,20 @@ IMPERSONATE_CONF_TEMPLATE = '''
147  
148  '''
149  
150 -def run_cmd(testdir, env, conf, name, socket, cmd, expected_failure):
151 +def run_cmd(testdir, env, conf, name, socket, cmd, keytab, expected_failure):
152  
153      logfile = conf['logfile']
154      testenv = env.copy()
155      testenv.update({'KRB5CCNAME': os.path.join(testdir, 't' + conf['prefix'] +
156                                                 '_impersonate.ccache'),
157 -                    'KRB5_KTNAME': os.path.join(testdir, PROXY_KTNAME),
158 +                    'KRB5_KTNAME': os.path.join(testdir, keytab),
159                      'KRB5_TRACE': os.path.join(testdir, 't' + conf['prefix'] +
160                                                 '_impersonate.trace'),
161                      'GSS_USE_PROXY': 'yes',
162                      'GSSPROXY_SOCKET': socket,
163                      'GSSPROXY_BEHAVIOR': 'REMOTE_FIRST'})
164  
165 +    print("\nTesting: [%s]" % (name,), file=logfile)
166      print("[COMMAND]\n%s\n[ENVIRONMENT]\n%s\n" % (cmd, testenv), file=logfile)
167      logfile.flush()
168  
169 @@ -74,45 +75,59 @@ def run(testdir, env, conf):
170      rets = []
171  
172      # Test all permitted
173 +    msg = "Impersonate"
174      socket = os.path.join(testdir, 'impersonate.socket')
175      cmd = ["./tests/t_impersonate", USR_NAME, HOST_GSS, PROXY_GSS,
176             path_prefix + 'impersonate.cache']
177 -    r = run_cmd(testdir, env, conf, "Impersonate", socket, cmd, False)
178 +    r = run_cmd(testdir, env, conf, msg, socket, cmd, PROXY_KTNAME, False)
179      rets.append(r)
180  
181 -    #Test fail
182 +    #Test self fail
183 +    msg = "Impersonate fail self"
184      socket = os.path.join(testdir, 'impersonate-proxyonly.socket')
185      cmd = ["./tests/t_impersonate", USR_NAME, HOST_GSS, PROXY_GSS,
186             path_prefix + 'impersonate.cache']
187 -    r = run_cmd(testdir, env, conf, "Impersonate fail self", socket, cmd, True)
188 +    r = run_cmd(testdir, env, conf, msg, socket, cmd, PROXY_KTNAME, True)
189      rets.append(r)
190  
191 -    #Test fail
192 +    #Test proxy fail
193 +    msg = "Impersonate fail proxy"
194      socket = os.path.join(testdir, 'impersonate-selfonly.socket')
195      cmd = ["./tests/t_impersonate", USR_NAME, HOST_GSS, PROXY_GSS,
196             path_prefix + 'impersonate.cache']
197 -    r = run_cmd(testdir, env, conf, "Impersonate fail proxy", socket, cmd, True)
198 +    r = run_cmd(testdir, env, conf, msg, socket, cmd, PROXY_KTNAME, True)
199      rets.append(r)
200  
201      #Test s4u2self half succeed
202 +    msg = "s4u2self delegation"
203      socket = os.path.join(testdir, 'impersonate-selfonly.socket')
204      cmd = ["./tests/t_impersonate", USR_NAME, HOST_GSS, PROXY_GSS,
205             path_prefix + 'impersonate.cache', 's4u2self']
206 -    r = run_cmd(testdir, env, conf, "s4u2self delegation", socket, cmd, False)
207 +    r = run_cmd(testdir, env, conf, msg, socket, cmd, PROXY_KTNAME, False)
208 +    rets.append(r)
209 +
210 +    #Test proxy to self succeed
211 +    msg = "Impersonate to self"
212 +    socket = os.path.join(testdir, 'impersonate-selfonly.socket')
213 +    cmd = ["./tests/t_impersonate", USR_NAME, HOST_GSS, HOST_GSS,
214 +           path_prefix + 'impersonate.cache', 's4u2proxy']
215 +    r = run_cmd(testdir, env, conf, msg, socket, cmd, SVC_KTNAME, False)
216      rets.append(r)
217  
218      #Test s4u2proxy half fail
219 +    msg = "s4u2proxy fail"
220      socket = os.path.join(testdir, 'impersonate-selfonly.socket')
221      cmd = ["./tests/t_impersonate", USR_NAME, HOST_GSS, PROXY_GSS,
222             path_prefix + 'impersonate.cache', 's4u2proxy']
223 -    r = run_cmd(testdir, env, conf, "s4u2proxy fail", socket, cmd, True)
224 +    r = run_cmd(testdir, env, conf, msg, socket, cmd, PROXY_KTNAME, True)
225      rets.append(r)
226  
227      #Test s4u2proxy half succeed
228 +    msg = "s4u2proxy"
229      socket = os.path.join(testdir, 'impersonate-proxyonly.socket')
230      cmd = ["./tests/t_impersonate", USR_NAME, HOST_GSS, PROXY_GSS,
231             path_prefix + 'impersonate.cache', 's4u2proxy']
232 -    r = run_cmd(testdir, env, conf, "s4u2proxy", socket, cmd, False)
233 +    r = run_cmd(testdir, env, conf, msg, socket, cmd, PROXY_KTNAME, False)
234      rets.append(r)
235  
236      # Reset back gssproxy conf