-
Notifications
You must be signed in to change notification settings - Fork 4
Expand file tree
/
Copy pathtest-spnego-proof-of-authentication.sh
More file actions
executable file
·361 lines (317 loc) · 13.4 KB
/
test-spnego-proof-of-authentication.sh
File metadata and controls
executable file
·361 lines (317 loc) · 13.4 KB
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
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
#!/usr/bin/env bash
# Proof-of-Concept: SPNEGO Authentication is Actually Required
# This script demonstrates that SPNEGO authentication is working by showing:
# 1. Without SPNEGO credentials: HTTP 407 (Proxy Authentication Required)
# 2. With SPNEGO credentials: HTTP 201 (Success)
set -euo pipefail
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
# Color codes
GREEN='\033[0;32m'
BLUE='\033[0;34m'
YELLOW='\033[1;33m'
RED='\033[0;31m'
BOLD='\033[1m'
NC='\033[0m'
log_step() { echo -e "${BLUE}${BOLD}$1${NC}"; }
log_success() { echo -e "${GREEN}[SUCCESS] ✓ $1${NC}"; }
log_error() { echo -e "${RED}[ERROR] ✗ $1${NC}"; }
log_info() { echo -e "${BOLD}[INFO] $1${NC}"; }
log_warning() { echo -e "${YELLOW}[WARNING] ⚠ $1${NC}"; }
echo ""
echo -e "${BOLD}╔════════════════════════════════════════════════════════════════════╗${NC}"
echo -e "${BOLD}║ ║${NC}"
echo -e "${BOLD}║ 🔒 PROOF: SPNEGO Authentication is Actually Working! 🔒 ║${NC}"
echo -e "${BOLD}║ ║${NC}"
echo -e "${BOLD}║ This test proves SPNEGO is required by the proxy by showing: ║${NC}"
echo -e "${BOLD}║ 1. WITHOUT SPNEGO → HTTP 407 (Proxy Auth Required) ║${NC}"
echo -e "${BOLD}║ 2. WITH SPNEGO → HTTP 201 (Success) ║${NC}"
echo -e "${BOLD}║ ║${NC}"
echo -e "${BOLD}╚════════════════════════════════════════════════════════════════════╝${NC}"
echo ""
# Check prerequisites
log_step "▶ Checking Prerequisites"
echo ""
if ! docker ps --format "{{.Names}}" | grep -q "apache-proxy"; then
log_error "SPNEGO proxy not running. Start with:"
log_error " cd \$SCRIPT_DIR/../tpi-telemetry-cli/test-integration"
log_error " docker-compose up -d"
exit 1
fi
log_success "SPNEGO proxy running (localhost:3128)"
# Get API key
if [ -n "${STAGING_API_KEY:-}" ]; then
API_KEY="$STAGING_API_KEY"
else
log_info "Enter your Broadcom Staging API key:"
read -rs -p "API Key: " API_KEY
echo ""
fi
if [ -z "$API_KEY" ]; then
log_error "API key is required"
exit 1
fi
# Create test data
TEST_DATA=$(mktemp)
cat > "$TEST_DATA" << 'EOF'
{
"telemetry-source": "spnego-proof-test",
"telemetry-timestamp": "2025-10-24T12:00:00Z",
"test-message": "Proof that SPNEGO authentication is required"
}
EOF
#############################################################################
# TEST 1: WITHOUT SPNEGO - Should fail with HTTP 407
#############################################################################
echo ""
echo -e "${BOLD}═══════════════════════════════════════════════════════════════════${NC}"
log_step "▶ TEST 1: Send WITHOUT SPNEGO Authentication"
echo -e "${BOLD}═══════════════════════════════════════════════════════════════════${NC}"
echo ""
log_info "Sending to: https://telemetry-staging.pivotal.io/components"
log_info "Via proxy: http://localhost:3128"
log_warning "NO Kerberos ticket, NO --negotiate flag"
echo ""
log_info "Expected: HTTP 407 (Proxy Authentication Required)"
echo ""
CURL_OUTPUT_1=$(mktemp)
CURL_STDERR_1=$(mktemp)
# Initialize failure flags
CURL_FAILED_407=false
CURL_FAILED_OTHER=false
# Send WITHOUT SPNEGO authentication
# We need to capture both the HTTP code and any error messages
set +e # Temporarily disable exit on error to capture curl's exit code
HTTP_CODE_1=$(curl \
--silent \
--show-error \
--write-out "%{http_code}" \
--output "$CURL_OUTPUT_1" \
--max-time 30 \
--proxy http://localhost:3128 \
-H "Authorization: Bearer ${API_KEY}" \
-H "Content-Type: application/x-telemetry-json-batch" \
-H "User-Agent: SPNEGOProofTest/1.0.0" \
--data-binary "@${TEST_DATA}" \
"https://telemetry-staging.pivotal.io/components" \
2>"$CURL_STDERR_1")
CURL_EXIT_CODE=$?
set -e # Re-enable exit on error
# If curl failed, check if it was due to 407
CURL_ERROR=$(cat "$CURL_STDERR_1" 2>/dev/null || echo "")
# Debug: show what curl actually returned (uncomment for troubleshooting)
# log_info "DEBUG: curl exit code: $CURL_EXIT_CODE"
# log_info "DEBUG: HTTP_CODE_1 from write-out: '$HTTP_CODE_1'"
# log_info "DEBUG: stderr content: '$CURL_ERROR'"
if [[ $CURL_EXIT_CODE -ne 0 ]] && echo "$CURL_ERROR" | grep -iq "407\|proxy.*auth"; then
HTTP_CODE_1="407"
CURL_FAILED_407=true
elif [[ $CURL_EXIT_CODE -ne 0 ]]; then
# Curl failed for some other reason
HTTP_CODE_1="000"
CURL_FAILED_OTHER=true
fi
echo ""
log_info "Result: HTTP $HTTP_CODE_1"
if [[ -n "$CURL_ERROR" ]] && [[ "$CURL_FAILED_407" == "false" ]]; then
log_warning "curl error: $CURL_ERROR"
fi
echo ""
if [[ "$HTTP_CODE_1" == "407" ]]; then
log_success "✓ PROXY REJECTED REQUEST (HTTP 407 - Proxy Authentication Required)"
log_success "✓ This proves SPNEGO authentication IS required!"
echo ""
log_info "What happened:"
echo " • curl tried to connect through the proxy"
echo " • Proxy responded: 407 Proxy Authentication Required"
echo " • curl failed because we didn't provide SPNEGO credentials"
echo ""
log_success "This is the EXPECTED behavior! The proxy is enforcing authentication."
echo ""
elif [[ "$HTTP_CODE_1" == "201" ]]; then
log_error "UNEXPECTED: Request succeeded without SPNEGO!"
log_error "This means the proxy is NOT requiring authentication"
log_error "Check your proxy configuration"
rm -f "$TEST_DATA" "$CURL_OUTPUT_1" "$CURL_STDERR_1"
exit 1
elif [[ "$CURL_FAILED_OTHER" == "true" ]]; then
log_error "curl failed for an unexpected reason (not 407)"
log_error "This could be a network issue, DNS failure, timeout, etc."
log_error "curl exit code: $CURL_EXIT_CODE"
if [[ -n "$CURL_ERROR" ]]; then
log_error "curl stderr: $CURL_ERROR"
else
log_error "curl stderr: (empty - no error message captured)"
fi
rm -f "$TEST_DATA" "$CURL_OUTPUT_1" "$CURL_STDERR_1"
exit 1
else
log_warning "Unexpected status: $HTTP_CODE_1"
log_info "This might still indicate authentication failure"
cat "$CURL_OUTPUT_1" 2>/dev/null || echo "(no additional info)"
fi
rm -f "$CURL_STDERR_1"
rm -f "$CURL_OUTPUT_1"
#############################################################################
# TEST 2: WITH SPNEGO - Should succeed with HTTP 201
#############################################################################
echo ""
echo -e "${BOLD}═══════════════════════════════════════════════════════════════════${NC}"
log_step "▶ TEST 2: Send WITH SPNEGO Authentication"
echo -e "${BOLD}═══════════════════════════════════════════════════════════════════${NC}"
echo ""
# Set up Kerberos
CLI_TEST_DIR="$(cd "${SCRIPT_DIR}/../tpi-telemetry-cli/test-integration" && pwd)"
export KRB5CCNAME="/tmp/krb5cc_spnego_proof_$$"
export KRB5_CONFIG="$CLI_TEST_DIR/krb5-host.conf"
# shellcheck disable=SC2329
cleanup() {
local exit_code=$?
rm -f "$TEST_DATA" "$CURL_OUTPUT_2" 2>/dev/null || true
if [[ -n "${KRB5CCNAME:-}" && -f "$KRB5CCNAME" ]]; then
rm -f "$KRB5CCNAME"
fi
exit "$exit_code"
}
trap cleanup EXIT INT TERM
USERNAME="testuser"
PASSWORD="testpass123"
DOMAIN="TEST.LOCAL"
PRINCIPAL="${USERNAME}@${DOMAIN}"
log_info "Authenticating to Kerberos KDC as $PRINCIPAL..."
# Create password file
PASSWD_FILE=$(mktemp)
chmod 0600 "$PASSWD_FILE"
echo "$PASSWORD" > "$PASSWD_FILE"
# Authenticate
if ! kinit "$PRINCIPAL" < "$PASSWD_FILE" 2>&1; then
rm -f "$PASSWD_FILE"
log_error "Kerberos authentication failed"
exit 1
fi
rm -f "$PASSWD_FILE"
# Verify ticket
if ! klist -s 2>/dev/null; then
log_error "No valid Kerberos ticket after kinit"
exit 1
fi
log_success "Kerberos ticket obtained"
echo ""
log_info "Sending to: https://telemetry-staging.pivotal.io/components"
log_info "Via proxy: http://localhost:3128"
log_success "WITH Kerberos ticket + --negotiate flag"
echo ""
log_info "Expected: HTTP 201 (Success)"
echo ""
CURL_OUTPUT_2=$(mktemp)
CURL_STDERR_2=$(mktemp)
# Send WITH SPNEGO authentication
set +e # Temporarily disable exit on error to capture curl's exit code
HTTP_CODE_2=$(curl \
--silent \
--show-error \
--write-out "%{http_code}" \
--output "$CURL_OUTPUT_2" \
--max-time 30 \
--proxy http://localhost:3128 \
--negotiate \
--proxy-negotiate \
-u : \
-H "Authorization: Bearer ${API_KEY}" \
-H "Content-Type: application/x-telemetry-json-batch" \
-H "User-Agent: SPNEGOProofTest/1.0.0" \
--data-binary "@${TEST_DATA}" \
"https://telemetry-staging.pivotal.io/components" \
2>"$CURL_STDERR_2")
CURL_EXIT_CODE_2=$?
set -e # Re-enable exit on error
# Check for curl errors
CURL_ERROR_2=$(cat "$CURL_STDERR_2" 2>/dev/null || echo "")
if [[ $CURL_EXIT_CODE_2 -ne 0 ]]; then
HTTP_CODE_2="000"
fi
echo ""
log_info "Result: HTTP $HTTP_CODE_2"
if [[ -n "$CURL_ERROR_2" ]]; then
log_warning "curl error: $CURL_ERROR_2"
fi
echo ""
if [[ "$HTTP_CODE_2" == "201" ]]; then
log_success "✓ REQUEST SUCCEEDED (HTTP 201 - Created)"
log_success "✓ This proves SPNEGO authentication WORKED!"
echo ""
log_info "What happened:"
echo " • kinit obtained a Kerberos ticket"
echo " • curl generated a SPNEGO token from the ticket"
echo " • Proxy accepted the SPNEGO token (authenticated!)"
echo " • Request forwarded to staging endpoint"
echo " • Endpoint returned 201 (data accepted)"
echo ""
elif [[ "$HTTP_CODE_2" == "407" ]]; then
log_error "FAILED: Still got HTTP 407 with SPNEGO credentials"
log_error "This means SPNEGO negotiation failed"
cat "$CURL_OUTPUT_2" 2>/dev/null || echo "(no additional info)"
rm -f "$CURL_STDERR_2"
exit 1
elif [[ "$HTTP_CODE_2" == "000" ]]; then
log_error "FAILED: curl error (not HTTP 407)"
log_error "This could be a network issue, timeout, or other problem"
log_error "Error: $CURL_ERROR_2"
rm -f "$CURL_STDERR_2"
exit 1
else
log_warning "Unexpected status: $HTTP_CODE_2"
cat "$CURL_OUTPUT_2" 2>/dev/null || echo "(no additional info)"
fi
rm -f "$CURL_STDERR_2"
rm -f "$CURL_OUTPUT_2"
#############################################################################
# SUMMARY
#############################################################################
echo ""
echo -e "${BOLD}═══════════════════════════════════════════════════════════════════${NC}"
log_step "▶ PROOF SUMMARY"
echo -e "${BOLD}═══════════════════════════════════════════════════════════════════${NC}"
echo ""
if [[ "$HTTP_CODE_1" == "407" ]] && [[ "$HTTP_CODE_2" == "201" ]]; then
echo -e "${GREEN}${BOLD}"
echo "╔═══════════════════════════════════════════════════════════════╗"
echo "║ ║"
echo "║ ✓ PROOF COMPLETE: SPNEGO AUTHENTICATION IS WORKING! ✓ ║"
echo "║ ║"
echo "╚═══════════════════════════════════════════════════════════════╝"
echo -e "${NC}"
echo ""
echo -e "${BOLD}What we proved:${NC}"
echo ""
echo " 1. WITHOUT SPNEGO credentials:"
echo " • HTTP 407 (Proxy Authentication Required)"
echo " • Proxy rejected the request"
echo ""
echo " 2. WITH SPNEGO credentials:"
echo " • HTTP 201 (Success)"
echo " • Proxy accepted the SPNEGO token"
echo " • Data reached the telemetry endpoint"
echo ""
echo -e "${BOLD}This proves:${NC}"
echo " ✓ The proxy REQUIRES authentication (not bypassing)"
echo " ✓ SPNEGO negotiation is WORKING correctly"
echo " ✓ Kerberos tickets are being generated and used"
echo " ✓ The curl --negotiate flag is functioning"
echo " ✓ The centralizer code will work in production"
echo ""
echo -e "${GREEN}${BOLD}SPNEGO authentication is production-ready! 🚀${NC}"
echo ""
exit 0
else
echo -e "${RED}${BOLD}PROOF INCOMPLETE${NC}"
echo ""
echo "Expected results:"
echo " • Test 1 (no SPNEGO): HTTP 407"
echo " • Test 2 (with SPNEGO): HTTP 201"
echo ""
echo "Actual results:"
echo " • Test 1: HTTP $HTTP_CODE_1"
echo " • Test 2: HTTP $HTTP_CODE_2"
echo ""
exit 1
fi