+static void process_proxy_debug(int indent, const char *format, ...)
+ {
+ static const char indentation[] =
+ ">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>"
+ ">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>"; /* That's 80 > */
+ char my_format[256];
+ va_list args;
+
+ BIO_snprintf(my_format, sizeof(my_format), "%*.*s %s",
+ indent, indent, indentation, format);
+
+ va_start(args, format);
+ vfprintf(stderr, my_format, args);
+ va_end(args);
+ }
+/* Priority levels:
+ 0 [!]var, ()
+ 1 & ^
+ 2 |
+*/
+static int process_proxy_cond_adders(unsigned int letters[26],
+ const char *cond, const char **cond_end, int *pos, int indent);
+static int process_proxy_cond_val(unsigned int letters[26],
+ const char *cond, const char **cond_end, int *pos, int indent)
+ {
+ int c;
+ int ok = 1;
+ int negate = 0;
+
+ while(isspace((int)*cond))
+ {
+ cond++; (*pos)++;
+ }
+ c = *cond;
+
+ if (debug)
+ process_proxy_debug(indent,
+ "Start process_proxy_cond_val at position %d: %s\n",
+ *pos, cond);
+
+ while(c == '!')
+ {
+ negate = !negate;
+ cond++; (*pos)++;
+ while(isspace((int)*cond))
+ {
+ cond++; (*pos)++;
+ }
+ c = *cond;
+ }
+
+ if (c == '(')
+ {
+ cond++; (*pos)++;
+ ok = process_proxy_cond_adders(letters, cond, cond_end, pos,
+ indent + 1);
+ cond = *cond_end;
+ if (ok < 0)
+ goto end;
+ while(isspace((int)*cond))
+ {
+ cond++; (*pos)++;
+ }
+ c = *cond;
+ if (c != ')')
+ {
+ fprintf(stderr,
+ "Weird condition character in position %d: "
+ "%c\n", *pos, c);
+ ok = -1;
+ goto end;
+ }
+ cond++; (*pos)++;
+ }
+ else if (isascii(c) && isalpha(c))
+ {
+ if (islower(c))
+ c = toupper(c);
+ ok = letters[c - 'A'];
+ cond++; (*pos)++;
+ }
+ else
+ {
+ fprintf(stderr,
+ "Weird condition character in position %d: "
+ "%c\n", *pos, c);
+ ok = -1;
+ goto end;
+ }
+ end:
+ *cond_end = cond;
+ if (ok >= 0 && negate)
+ ok = !ok;
+
+ if (debug)
+ process_proxy_debug(indent,
+ "End process_proxy_cond_val at position %d: %s, returning %d\n",
+ *pos, cond, ok);
+
+ return ok;
+ }
+static int process_proxy_cond_multipliers(unsigned int letters[26],
+ const char *cond, const char **cond_end, int *pos, int indent)
+ {
+ int ok;
+ char c;
+
+ if (debug)
+ process_proxy_debug(indent,
+ "Start process_proxy_cond_multipliers at position %d: %s\n",
+ *pos, cond);
+
+ ok = process_proxy_cond_val(letters, cond, cond_end, pos, indent + 1);
+ cond = *cond_end;
+ if (ok < 0)
+ goto end;
+
+ while(ok >= 0)
+ {
+ while(isspace((int)*cond))
+ {
+ cond++; (*pos)++;
+ }
+ c = *cond;
+
+ switch(c)
+ {
+ case '&':
+ case '^':
+ {
+ int save_ok = ok;
+
+ cond++; (*pos)++;
+ ok = process_proxy_cond_val(letters,
+ cond, cond_end, pos, indent + 1);
+ cond = *cond_end;
+ if (ok < 0)
+ break;
+
+ switch(c)
+ {
+ case '&':
+ ok &= save_ok;
+ break;
+ case '^':
+ ok ^= save_ok;
+ break;
+ default:
+ fprintf(stderr, "SOMETHING IS SERIOUSLY WRONG!"
+ " STOPPING\n");
+ EXIT(1);
+ }
+ }
+ break;
+ default:
+ goto end;
+ }
+ }
+ end:
+ if (debug)
+ process_proxy_debug(indent,
+ "End process_proxy_cond_multipliers at position %d: %s, returning %d\n",
+ *pos, cond, ok);
+
+ *cond_end = cond;
+ return ok;
+ }
+static int process_proxy_cond_adders(unsigned int letters[26],
+ const char *cond, const char **cond_end, int *pos, int indent)
+ {
+ int ok;
+ char c;
+
+ if (debug)
+ process_proxy_debug(indent,
+ "Start process_proxy_cond_adders at position %d: %s\n",
+ *pos, cond);
+
+ ok = process_proxy_cond_multipliers(letters, cond, cond_end, pos,
+ indent + 1);
+ cond = *cond_end;
+ if (ok < 0)
+ goto end;
+
+ while(ok >= 0)
+ {
+ while(isspace((int)*cond))
+ {
+ cond++; (*pos)++;
+ }
+ c = *cond;
+
+ switch(c)
+ {
+ case '|':
+ {
+ int save_ok = ok;
+
+ cond++; (*pos)++;
+ ok = process_proxy_cond_multipliers(letters,
+ cond, cond_end, pos, indent + 1);
+ cond = *cond_end;
+ if (ok < 0)
+ break;
+
+ switch(c)
+ {
+ case '|':
+ ok |= save_ok;
+ break;
+ default:
+ fprintf(stderr, "SOMETHING IS SERIOUSLY WRONG!"
+ " STOPPING\n");
+ EXIT(1);
+ }
+ }
+ break;
+ default:
+ goto end;
+ }
+ }
+ end:
+ if (debug)
+ process_proxy_debug(indent,
+ "End process_proxy_cond_adders at position %d: %s, returning %d\n",
+ *pos, cond, ok);
+
+ *cond_end = cond;
+ return ok;
+ }
+
+static int process_proxy_cond(unsigned int letters[26],
+ const char *cond, const char **cond_end)
+ {
+ int pos = 1;
+ return process_proxy_cond_adders(letters, cond, cond_end, &pos, 1);
+ }
+
+static int MS_CALLBACK app_verify_callback(X509_STORE_CTX *ctx, void *arg)
+ {
+ int ok=1;
+ struct app_verify_arg *cb_arg = arg;
+ unsigned int letters[26]; /* only used with proxy_auth */
+
+ if (cb_arg->app_verify)
+ {
+ char *s = NULL,buf[256];
+
+ fprintf(stderr, "In app_verify_callback, allowing cert. ");
+ fprintf(stderr, "Arg is: %s\n", cb_arg->string);
+ fprintf(stderr, "Finished printing do we have a context? 0x%p a cert? 0x%p\n",
+ (void *)ctx, (void *)ctx->cert);
+ if (ctx->cert)
+ s=X509_NAME_oneline(X509_get_subject_name(ctx->cert),buf,256);
+ if (s != NULL)
+ {
+ fprintf(stderr,"cert depth=%d %s\n",ctx->error_depth,buf);
+ }
+ return(1);
+ }
+ if (cb_arg->proxy_auth)
+ {
+ int found_any = 0, i;
+ char *sp;
+
+ for(i = 0; i < 26; i++)
+ letters[i] = 0;
+ for(sp = cb_arg->proxy_auth; *sp; sp++)
+ {
+ int c = *sp;
+ if (isascii(c) && isalpha(c))
+ {
+ if (islower(c))
+ c = toupper(c);
+ letters[c - 'A'] = 1;
+ }
+ }
+
+ fprintf(stderr,
+ " Initial proxy rights = ");
+ for(i = 0; i < 26; i++)
+ if (letters[i])
+ {
+ fprintf(stderr, "%c", i + 'A');
+ found_any = 1;
+ }
+ if (!found_any)
+ fprintf(stderr, "none");
+ fprintf(stderr, "\n");
+
+ X509_STORE_CTX_set_ex_data(ctx,
+ get_proxy_auth_ex_data_idx(),letters);
+ }
+ if (cb_arg->allow_proxy_certs)
+ {
+ X509_STORE_CTX_set_flags(ctx, X509_V_FLAG_ALLOW_PROXY_CERTS);
+ }
+
+#ifndef OPENSSL_NO_X509_VERIFY
+# ifdef OPENSSL_FIPS
+ if(s->version == TLS1_VERSION)
+ FIPS_allow_md5(1);
+# endif
+ ok = X509_verify_cert(ctx);
+# ifdef OPENSSL_FIPS
+ if(s->version == TLS1_VERSION)
+ FIPS_allow_md5(0);
+# endif
+#endif
+
+ if (cb_arg->proxy_auth)
+ {
+ if (ok > 0)
+ {
+ const char *cond_end = NULL;
+
+ ok = process_proxy_cond(letters,
+ cb_arg->proxy_cond, &cond_end);
+
+ if (ok < 0)
+ EXIT(3);
+ if (*cond_end)
+ {
+ fprintf(stderr, "Stopped processing condition before it's end.\n");
+ ok = 0;
+ }
+ if (!ok)
+ fprintf(stderr, "Proxy rights check with condition '%s' proved invalid\n",
+ cb_arg->proxy_cond);
+ else
+ fprintf(stderr, "Proxy rights check with condition '%s' proved valid\n",
+ cb_arg->proxy_cond);
+ }
+ }
+ return(ok);
+ }
+
+#ifndef OPENSSL_NO_RSA