43#include <openssl/hmac.h>
44#include <openssl/bio.h>
45#include <openssl/buffer.h>
46#include <openssl/err.h>
47#include <openssl/ssl.h>
56# include "sys/param.h"
59#if OPENSSL_VERSION_NUMBER < 0x10100000L
61 HMAC_CTX *ctx = (HMAC_CTX *)OPENSSL_malloc(
sizeof(HMAC_CTX));
62 if (ctx) HMAC_CTX_init(ctx);
68 HMAC_CTX_cleanup(ctx);
78int parseURL(
char *url,
char *host,
int &port,
char **path) {
84 char *p = strstr(url,
"//");
91 char *p2 = strchr(p,
'/');
97 int l = std::min((
int)(p2 - p), (
int)
sizeof (buf));
102 p = strchr(buf,
':');
104 int l = std::min((
int)(p - buf), (
int)
sizeof (buf));
105 strncpy(host, buf, l);
122void Tobase64(
const unsigned char *input,
int length,
char *out) {
130 b64 = BIO_new(BIO_f_base64());
132 bmem = BIO_new(BIO_s_mem());
134 BIO_write(b64, input, length);
136 if (BIO_flush(b64) <= 0) {
141 BIO_get_mem_ptr(b64, &bptr);
144 memcpy(out, bptr->data, bptr->length);
145 out[bptr->length] =
'\0';
160 if (c >=
'a' && c <=
'f') {
170bool Fromhexdigest(
const unsigned char *input,
int length,
unsigned char *out) {
171 for (
int idx=0; idx < length; idx += 2) {
174 if ((upper < 0) || (lower < 0)) {
177 out[idx/2] = (upper << 4) + lower;
186 sprintf(buf,
"%ld", i);
195 char *ptr = strchr((
char *)s, c);
198 return strchr((
char *)s,
'\0');
234#if OPENSSL_VERSION_NUMBER >= 0x30000000L
242 unsigned char mdbuf[EVP_MAX_MD_SIZE];
256 if (!fn || !secent) {
260#if OPENSSL_VERSION_NUMBER >= 0x30000000L
262 mac = EVP_MAC_fetch(0,
"sha256", 0);
263 ctx = EVP_MAC_CTX_new(mac);
270 EVP_MAC_init(ctx, (
const unsigned char *) key, strlen(key), 0);
274 EVP_MAC_update(ctx, (
const unsigned char *) fn,
277 EVP_MAC_update(ctx, (
const unsigned char *) &request,
281 EVP_MAC_update(ctx, (
const unsigned char *) secent->
name,
282 strlen(secent->
name) + 1);
285 EVP_MAC_update(ctx, (
const unsigned char *) secent->
vorg,
286 strlen(secent->
vorg) + 1);
289 EVP_MAC_update(ctx, (
const unsigned char *) secent->
host,
290 strlen(secent->
host) + 1);
293 EVP_MAC_update(ctx, (
const unsigned char *) secent->
moninfo,
296 localtime_r(&tim, &tms);
297 strftime(buf,
sizeof (buf),
"%s", &tms);
298 EVP_MAC_update(ctx, (
const unsigned char *) buf,
301 EVP_MAC_final(ctx, mdbuf, &len, EVP_MAX_MD_SIZE);
303 EVP_MAC_CTX_free(ctx);
316 HMAC_Init_ex(ctx, (
const void *) key, strlen(key), EVP_sha256(), 0);
320 HMAC_Update(ctx, (
const unsigned char *) fn,
323 HMAC_Update(ctx, (
const unsigned char *) &request,
327 HMAC_Update(ctx, (
const unsigned char *) secent->
name,
328 strlen(secent->
name) + 1);
331 HMAC_Update(ctx, (
const unsigned char *) secent->
vorg,
332 strlen(secent->
vorg) + 1);
335 HMAC_Update(ctx, (
const unsigned char *) secent->
host,
336 strlen(secent->
host) + 1);
339 HMAC_Update(ctx, (
const unsigned char *) secent->
moninfo,
342 localtime_r(&tim, &tms);
343 strftime(buf,
sizeof (buf),
"%s", &tms);
344 HMAC_Update(ctx, (
const unsigned char *) buf,
347 HMAC_Final(ctx, mdbuf, &len);
360 if (h1 == h2)
return 0;
365 return strcmp(h1, h2);
373 char *r = (
char *) malloc(l + 1);
377 for (i = 0; i < l; i++) {
380 char savec = str[i + 3];
383 r[j] = strtol(str + i + 1, 0, 16);
387 }
else r[j] = str[i];
402 char *r = (
char *) malloc(l*3 + 1);
406 for (i = 0; i < l; i++) {
411 strcpy(r + j,
"%20");
415 strcpy(r + j,
"%5B");
419 strcpy(r + j,
"%5D");
423 strcpy(r + j,
"%3A");
431 strcpy(r + j,
"%23");
435 strcpy(r + j,
"%0A");
439 strcpy(r + j,
"%0D");
443 strcpy(r + j,
"%3D");
461 char *r = (
char *) malloc(l*6 + 1);
465 for (i = 0; i < l; i++) {
470 strcpy(r + j,
""");
474 strcpy(r + j,
"&");
478 strcpy(r + j,
"<");
482 strcpy(r + j,
">");
486 strcpy(r + j,
"'");
576 case 100:
return "Continue";
577 case 101:
return "Switching Protocols";
578 case 102:
return "Processing";
579 case 103:
return "Early Hints";
582 case 200:
return "OK";
583 case 201:
return "Created";
584 case 202:
return "Accepted";
585 case 203:
return "Non-Authoritative Information";
586 case 204:
return "No Content";
587 case 205:
return "Reset Content";
588 case 206:
return "Partial Content";
589 case 207:
return "Multi-Status";
590 case 208:
return "Already Reported";
591 case 226:
return "IM Used";
594 case 300:
return "Multiple Choices";
595 case 301:
return "Moved Permanently";
596 case 302:
return "Found";
597 case 303:
return "See Other";
598 case 304:
return "Not Modified";
599 case 305:
return "Use Proxy";
600 case 307:
return "Temporary Redirect";
601 case 308:
return "Permanent Redirect";
604 case 400:
return "Bad Request";
605 case 401:
return "Unauthorized";
606 case 402:
return "Payment Required";
607 case 403:
return "Forbidden";
608 case 404:
return "Not Found";
609 case 405:
return "Method Not Allowed";
610 case 406:
return "Not Acceptable";
611 case 407:
return "Proxy Authentication Required";
612 case 408:
return "Request Timeout";
613 case 409:
return "Conflict";
614 case 410:
return "Gone";
615 case 411:
return "Length Required";
616 case 412:
return "Precondition Failed";
617 case 413:
return "Payload Too Large";
618 case 414:
return "URI Too Long";
619 case 415:
return "Unsupported Media Type";
620 case 416:
return "Range Not Satisfiable";
621 case 417:
return "Expectation Failed";
622 case 418:
return "I'm a teapot";
623 case 421:
return "Misdirected Request";
624 case 422:
return "Unprocessable Entity";
625 case 423:
return "Locked";
626 case 424:
return "Failed Dependency";
627 case 425:
return "Too Early";
628 case 426:
return "Upgrade Required";
629 case 428:
return "Precondition Required";
630 case 429:
return "Too Many Requests";
631 case 431:
return "Request Header Fields Too Large";
632 case 451:
return "Unavailable For Legal Reasons";
635 case 500:
return "Internal Server Error";
636 case 501:
return "Not Implemented";
637 case 502:
return "Bad Gateway";
638 case 503:
return "Service Unavailable";
639 case 504:
return "Gateway Timeout";
640 case 505:
return "HTTP Version Not Supported";
641 case 506:
return "Variant Also Negotiates";
642 case 507:
return "Insufficient Storage";
643 case 508:
return "Loop Detected";
644 case 510:
return "Not Extended";
645 case 511:
return "Network Authentication Required";
649 case 100 ... 199:
return "Informational";
650 case 200 ... 299:
return "Success";
651 case 300 ... 399:
return "Redirection";
652 case 400 ... 499:
return "Client Error";
653 case 500 ... 599:
return "Server Error";
654 default:
return "Unknown";
void BIO_set_flags(BIO *bio, int flags)
int parseURL(char *url, char *host, int &port, char **path)
void Tobase64(const unsigned char *input, int length, char *out)
int compareHash(const char *h1, const char *h2)
static HMAC_CTX * HMAC_CTX_new()
bool Fromhexdigest(const unsigned char *input, int length, unsigned char *out)
char * unquote(char *str)
char * quote(const char *str)
char * escapeXML(const char *str)
static int char_to_int(int c)
int mapErrNoToHttp(int errNo)
char * mystrchrnul(const char *s, int c)
static void HMAC_CTX_free(HMAC_CTX *ctx)
void calcHashes(char *hash, const char *fn, kXR_int16 request, XrdSecEntity *secent, time_t tim, const char *key)
std::string httpStatusToString(int status)
Utility functions for XrdHTTP.
@ HTTP_INSUFFICIENT_STORAGE
@ HTTP_SERVICE_UNAVAILABLE
@ HTTP_INTERNAL_SERVER_ERROR
@ HTTP_UNPROCESSABLE_ENTITY
char * vorg
Entity's virtual organization(s)
char * name
Entity's name.
char * moninfo
Information for monitoring.
char * host
Entity's host name dnr dependent.