Anforderungen  |   Konzepte  |   Entwurf  |   Entwicklung  |   Qualitätssicherung  |   Lebenszyklus  |   Steuerung
 
 
 
 


Quelle  test_auth_proxy.js   Sprache: JAVA

 
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */


/**
 * This tests the automatic login to the proxy with password,
 * if the password is stored and the browser is restarted.
 *
 * <copied from="test_authentication.js"/>
 */


"use strict";

const { HttpServer } = ChromeUtils.importESModule(
  "resource://testing-common/httpd.sys.mjs"
);

const FLAG_RETURN_FALSE = 1 << 0;
const FLAG_WRONG_PASSWORD = 1 << 1;
const FLAG_PREVIOUS_FAILED = 1 << 2;

function AuthPrompt2(proxyFlags, hostFlags) {
  this.proxyCred.flags = proxyFlags;
  this.hostCred.flags = hostFlags;
}
AuthPrompt2.prototype = {
  proxyCred: {
    user: "proxy",
    pass: "guest",
    realmExpected: "intern",
    flags: 0,
  },
  hostCred: { user: "host", pass: "guest", realmExpected: "extern", flags: 0 },

  QueryInterface: ChromeUtils.generateQI(["nsIAuthPrompt2"]),

  promptAuth: function ap2_promptAuth(channel, encryptionLevel, authInfo) {
    try {
      // never HOST and PROXY set at the same time in prompt
      Assert.equal(
        (authInfo.flags & Ci.nsIAuthInformation.AUTH_HOST) != 0,
        (authInfo.flags & Ci.nsIAuthInformation.AUTH_PROXY) == 0
      );

      var isProxy = (authInfo.flags & Ci.nsIAuthInformation.AUTH_PROXY) != 0;
      var cred = isProxy ? this.proxyCred : this.hostCred;

      dump(
        "with flags: " +
          ((cred.flags & FLAG_WRONG_PASSWORD) != 0 ? "wrong password" : "") +
          " " +
          ((cred.flags & FLAG_PREVIOUS_FAILED) != 0 ? "previous failed" : "") +
          " " +
          ((cred.flags & FLAG_RETURN_FALSE) != 0 ? "return false" : "") +
          "\n"
      );

      // PROXY properly set by necko (checked using realm)
      Assert.equal(cred.realmExpected, authInfo.realm);

      // PREVIOUS_FAILED properly set by necko
      Assert.equal(
        (cred.flags & FLAG_PREVIOUS_FAILED) != 0,
        (authInfo.flags & Ci.nsIAuthInformation.PREVIOUS_FAILED) != 0
      );

      if (cred.flags & FLAG_RETURN_FALSE) {
        cred.flags |= FLAG_PREVIOUS_FAILED;
        cred.flags &= ~FLAG_RETURN_FALSE;
        return false;
      }

      authInfo.username = cred.user;
      if (cred.flags & FLAG_WRONG_PASSWORD) {
        authInfo.password = cred.pass + ".wrong";
        cred.flags |= FLAG_PREVIOUS_FAILED;
        // Now clear the flag to avoid an infinite loop
        cred.flags &= ~FLAG_WRONG_PASSWORD;
      } else {
        authInfo.password = cred.pass;
        cred.flags &= ~FLAG_PREVIOUS_FAILED;
      }
    } catch (e) {
      do_throw(e);
    }
    return true;
  },

  asyncPromptAuth: function ap2_async(
    channel,
    callback,
    context,
    encryptionLevel,
    authInfo
  ) {
    var me = this;
    var allOverAndDead = false;
    executeSoon(function () {
      try {
        if (allOverAndDead) {
          throw new Error("already canceled");
        }
        var ret = me.promptAuth(channel, encryptionLevel, authInfo);
        if (!ret) {
          callback.onAuthCancelled(context, true);
        } else {
          callback.onAuthAvailable(context, authInfo);
        }
        allOverAndDead = true;
      } catch (e) {
        do_throw(e);
      }
    });
    return new Cancelable(function () {
      if (allOverAndDead) {
        throw new Error("can't cancel, already ran");
      }
      callback.onAuthAvailable(context, authInfo);
      allOverAndDead = true;
    });
  },
};

function Cancelable(onCancelFunc) {
  this.onCancelFunc = onCancelFunc;
}
Cancelable.prototype = {
  QueryInterface: ChromeUtils.generateQI(["nsICancelable"]),
  cancel: function cancel() {
    try {
      this.onCancelFunc();
    } catch (e) {
      do_throw(e);
    }
  },
};

function Requestor(proxyFlags, hostFlags) {
  this.proxyFlags = proxyFlags;
  this.hostFlags = hostFlags;
}
Requestor.prototype = {
  QueryInterface: ChromeUtils.generateQI(["nsIInterfaceRequestor"]),

  getInterface: function requestor_gi(iid) {
    if (iid.equals(Ci.nsIAuthPrompt)) {
      dump("authprompt1 not implemented\n");
      throw Components.Exception("", Cr.NS_ERROR_NO_INTERFACE);
    }
    if (iid.equals(Ci.nsIAuthPrompt2)) {
      try {
        // Allow the prompt to store state by caching it here
        if (!this.prompt2) {
          this.prompt2 = new AuthPrompt2(this.proxyFlags, this.hostFlags);
        }
        return this.prompt2;
      } catch (e) {
        do_throw(e);
      }
    }
    throw Components.Exception("", Cr.NS_ERROR_NO_INTERFACE);
  },

  prompt2: null,
};

var listener = {
  expectedCode: -1, // uninitialized

  onStartRequest: function test_onStartR(request) {
    try {
      // Proxy auth cancellation return failures to avoid spoofing
      if (
        !Components.isSuccessCode(request.status) &&
        this.expectedCode != 407
      ) {
        do_throw("Channel should have a success code!");
      }

      if (!(request instanceof Ci.nsIHttpChannel)) {
        do_throw("Expecting an HTTP channel");
      }

      Assert.equal(this.expectedCode, request.responseStatus);
      // If we expect 200, the request should have succeeded
      Assert.equal(this.expectedCode == 200, request.requestSucceeded);

      var cookie = "";
      try {
        cookie = request.getRequestHeader("Cookie");
      } catch (e) {}
      Assert.equal(cookie, "");
    } catch (e) {
      do_throw("Unexpected exception: " + e);
    }

    throw Components.Exception("", Cr.NS_ERROR_ABORT);
  },

  onDataAvailable: function test_ODA() {
    do_throw("Should not get any data!");
  },

  onStopRequest: function test_onStopR(request, status) {
    Assert.equal(status, Cr.NS_ERROR_ABORT);

    if (current_test < tests.length - 1) {
      // First, need to clear the auth cache
      Cc["@mozilla.org/network/http-auth-manager;1"]
        .getService(Ci.nsIHttpAuthManager)
        .clearAll();

      current_test++;
      tests[current_test]();
    } else {
      do_test_pending();
      httpserv.stop(do_test_finished);
    }

    do_test_finished();
  },
};

function makeChan(url) {
  if (!url) {
    url = "http://somesite/";
  }

  return NetUtil.newChannel({
    uri: url,
    loadUsingSystemPrincipal: true,
  }).QueryInterface(Ci.nsIHttpChannel);
}

var current_test = 0;
var httpserv = null;

function run_test() {
  httpserv = new HttpServer();
  httpserv.registerPathHandler("/", proxyAuthHandler);
  httpserv.identity.add("http""somesite", 80);
  httpserv.start(-1);

  Services.prefs.setCharPref("network.proxy.http""localhost");
  Services.prefs.setIntPref(
    "network.proxy.http_port",
    httpserv.identity.primaryPort
  );
  Services.prefs.setCharPref("network.proxy.no_proxies_on""");
  Services.prefs.setIntPref("network.proxy.type", 1);

  // Turn off the authentication dialog blocking for this test.
  Services.prefs.setIntPref("network.auth.subresource-http-auth-allow", 2);
  Services.prefs.setBoolPref(
    "network.auth.non-web-content-triggered-resources-http-auth-allow",
    true
  );

  registerCleanupFunction(() => {
    Services.prefs.clearUserPref("network.proxy.http");
    Services.prefs.clearUserPref("network.proxy.http_port");
    Services.prefs.clearUserPref("network.proxy.no_proxies_on");
    Services.prefs.clearUserPref("network.proxy.type");
    Services.prefs.clearUserPref("network.auth.subresource-http-auth-allow");
    Services.prefs.clearUserPref(
      "network.auth.non-web-content-triggered-resources-http-auth-allow"
    );
  });

  tests[current_test]();
}

function test_proxy_returnfalse() {
  dump("\ntest: proxy returnfalse\n");
  var chan = makeChan();
  chan.notificationCallbacks = new Requestor(FLAG_RETURN_FALSE, 0);
  listener.expectedCode = 407; // Proxy Unauthorized
  chan.asyncOpen(listener);

  do_test_pending();
}

function test_proxy_wrongpw() {
  dump("\ntest: proxy wrongpw\n");
  var chan = makeChan();
  chan.notificationCallbacks = new Requestor(FLAG_WRONG_PASSWORD, 0);
  listener.expectedCode = 200; // Eventually OK
  chan.asyncOpen(listener);
  do_test_pending();
}

function test_all_ok() {
  dump("\ntest: all ok\n");
  var chan = makeChan();
  chan.notificationCallbacks = new Requestor(0, 0);
  listener.expectedCode = 200; // OK
  chan.asyncOpen(listener);
  do_test_pending();
}

function test_proxy_407_cookie() {
  var chan = makeChan();
  chan.notificationCallbacks = new Requestor(FLAG_RETURN_FALSE, 0);
  chan.setRequestHeader("X-Set-407-Cookie""1"false);
  listener.expectedCode = 407; // Proxy Unauthorized
  chan.asyncOpen(listener);

  do_test_pending();
}

function test_proxy_200_cookie() {
  var chan = makeChan();
  chan.notificationCallbacks = new Requestor(0, 0);
  chan.setRequestHeader("X-Set-407-Cookie""1"false);
  listener.expectedCode = 200; // OK
  chan.asyncOpen(listener);
  do_test_pending();
}

function test_host_returnfalse() {
  dump("\ntest: host returnfalse\n");
  var chan = makeChan();
  chan.notificationCallbacks = new Requestor(0, FLAG_RETURN_FALSE);
  listener.expectedCode = 401; // Host Unauthorized
  chan.asyncOpen(listener);

  do_test_pending();
}

function test_host_wrongpw() {
  dump("\ntest: host wrongpw\n");
  var chan = makeChan();
  chan.notificationCallbacks = new Requestor(0, FLAG_WRONG_PASSWORD);
  listener.expectedCode = 200; // Eventually OK
  chan.asyncOpen(listener);
  do_test_pending();
}

function test_proxy_wrongpw_host_wrongpw() {
  dump("\ntest: proxy wrongpw, host wrongpw\n");
  var chan = makeChan();
  chan.notificationCallbacks = new Requestor(
    FLAG_WRONG_PASSWORD,
    FLAG_WRONG_PASSWORD
  );
  listener.expectedCode = 200; // OK
  chan.asyncOpen(listener);
  do_test_pending();
}

function test_proxy_wrongpw_host_returnfalse() {
  dump("\ntest: proxy wrongpw, host return false\n");
  var chan = makeChan();
  chan.notificationCallbacks = new Requestor(
    FLAG_WRONG_PASSWORD,
    FLAG_RETURN_FALSE
  );
  listener.expectedCode = 401; // Host Unauthorized
  chan.asyncOpen(listener);
  do_test_pending();
}

var tests = [
  test_proxy_returnfalse,
  test_proxy_wrongpw,
  test_all_ok,
  test_proxy_407_cookie,
  test_proxy_200_cookie,
  test_host_returnfalse,
  test_host_wrongpw,
  test_proxy_wrongpw_host_wrongpw,
  test_proxy_wrongpw_host_returnfalse,
];

// PATH HANDLERS

// Proxy
function proxyAuthHandler(metadata, response) {
  try {
    var realm = "intern";
    // btoa("proxy:guest"), but that function is not available here
    var expectedHeader = "Basic cHJveHk6Z3Vlc3Q=";

    var body;
    if (
      metadata.hasHeader("Proxy-Authorization") &&
      metadata.getHeader("Proxy-Authorization") == expectedHeader
    ) {
      dump("proxy password ok\n");
      response.setHeader(
        "Proxy-Authenticate",
        'Basic realm="' + realm + '"',
        false
      );

      hostAuthHandler(metadata, response);
    } else {
      dump("proxy password required\n");
      response.setStatusLine(
        metadata.httpVersion,
        407,
        "Unauthorized by HTTP proxy"
      );
      response.setHeader(
        "Proxy-Authenticate",
        'Basic realm="' + realm + '"',
        false
      );
      if (metadata.hasHeader("X-Set-407-Cookie")) {
        response.setHeader("Set-Cookie""chewy"false);
      }
      body = "failed";
      response.bodyOutputStream.write(body, body.length);
    }
  } catch (e) {
    do_throw(e);
  }
}

// Host /auth
function hostAuthHandler(metadata, response) {
  try {
    var realm = "extern";
    // btoa("host:guest"), but that function is not available here
    var expectedHeader = "Basic aG9zdDpndWVzdA==";

    var body;
    if (
      metadata.hasHeader("Authorization") &&
      metadata.getHeader("Authorization") == expectedHeader
    ) {
      dump("host password ok\n");
      response.setStatusLine(
        metadata.httpVersion,
        200,
        "OK, authorized for host"
      );
      response.setHeader(
        "WWW-Authenticate",
        'Basic realm="' + realm + '"',
        false
      );
      body = "success";
    } else {
      dump("host password required\n");
      response.setStatusLine(
        metadata.httpVersion,
        401,
        "Unauthorized by HTTP server host"
      );
      response.setHeader(
        "WWW-Authenticate",
        'Basic realm="' + realm + '"',
        false
      );
      body = "failed";
    }
    response.bodyOutputStream.write(body, body.length);
  } catch (e) {
    do_throw(e);
  }
}

Messung V0.5
C=92 H=99 G=95

¤ Dauer der Verarbeitung: 0.15 Sekunden  (vorverarbeitet)  ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

Beweissystem der NASA

Beweissystem Isabelle

NIST Cobol Testsuite

Cephes Mathematical Library

Wiener Entwicklungsmethode

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.






                                                                                                                                                                                                                                                                                                                                                                                                     


Neuigkeiten

     Aktuelles
     Motto des Tages

Software

     Produkte
     Quellcodebibliothek

Aktivitäten

     Artikel über Sicherheit
     Anleitung zur Aktivierung von SSL

Muße

     Gedichte
     Musik
     Bilder

Jenseits des Üblichen ....
    

Besucherstatistik

Besucherstatistik

Monitoring

Montastic status badge