Thursday, June 30, 2011

install jsocol's ratelimit

(playdoh)haoqili@host-7-136:09:41:17:~/dev/playdoh/playdoh/playdoh/django-ratelimit$ python setup.py install
installation outputs
running install
running bdist_egg
running egg_info
creating django_ratelimit.egg-info
writing requirements to django_ratelimit.egg-info/requires.txt
writing django_ratelimit.egg-info/PKG-INFO
writing top-level names to django_ratelimit.egg-info/top_level.txt
writing dependency_links to django_ratelimit.egg-info/dependency_links.txt
writing requirements to django_ratelimit.egg-info/requires.txt
writing django_ratelimit.egg-info/PKG-INFO
writing top-level names to django_ratelimit.egg-info/top_level.txt
writing dependency_links to django_ratelimit.egg-info/dependency_links.txt
writing manifest file 'django_ratelimit.egg-info/SOURCES.txt'
reading manifest file 'django_ratelimit.egg-info/SOURCES.txt'
reading manifest template 'MANIFEST.in'
writing manifest file 'django_ratelimit.egg-info/SOURCES.txt'
installing library code to build/bdist.macosx-10.4-x86_64/egg
running install_lib
running build_py
creating build
creating build/lib
creating build/lib/ratelimit
copying ratelimit/__init__.py -> build/lib/ratelimit
copying ratelimit/decorators.py -> build/lib/ratelimit
creating build/lib/ratelimit/backends
copying ratelimit/backends/__init__.py -> build/lib/ratelimit/backends
copying ratelimit/backends/cachebe.py -> build/lib/ratelimit/backends
creating build/bdist.macosx-10.4-x86_64
creating build/bdist.macosx-10.4-x86_64/egg
creating build/bdist.macosx-10.4-x86_64/egg/ratelimit
copying build/lib/ratelimit/__init__.py -> build/bdist.macosx-10.4-x86_64/egg/ratelimit
creating build/bdist.macosx-10.4-x86_64/egg/ratelimit/backends
copying build/lib/ratelimit/backends/__init__.py -> build/bdist.macosx-10.4-x86_64/egg/ratelimit/backends
copying build/lib/ratelimit/backends/cachebe.py -> build/bdist.macosx-10.4-x86_64/egg/ratelimit/backends
copying build/lib/ratelimit/decorators.py -> build/bdist.macosx-10.4-x86_64/egg/ratelimit
byte-compiling build/bdist.macosx-10.4-x86_64/egg/ratelimit/__init__.py to __init__.pyc
byte-compiling build/bdist.macosx-10.4-x86_64/egg/ratelimit/backends/__init__.py to __init__.pyc
byte-compiling build/bdist.macosx-10.4-x86_64/egg/ratelimit/backends/cachebe.py to cachebe.pyc
byte-compiling build/bdist.macosx-10.4-x86_64/egg/ratelimit/decorators.py to decorators.pyc
creating build/bdist.macosx-10.4-x86_64/egg/EGG-INFO
copying django_ratelimit.egg-info/PKG-INFO -> build/bdist.macosx-10.4-x86_64/egg/EGG-INFO
copying django_ratelimit.egg-info/SOURCES.txt -> build/bdist.macosx-10.4-x86_64/egg/EGG-INFO
copying django_ratelimit.egg-info/dependency_links.txt -> build/bdist.macosx-10.4-x86_64/egg/EGG-INFO
copying django_ratelimit.egg-info/requires.txt -> build/bdist.macosx-10.4-x86_64/egg/EGG-INFO
copying django_ratelimit.egg-info/top_level.txt -> build/bdist.macosx-10.4-x86_64/egg/EGG-INFO
zip_safe flag not set; analyzing archive contents...
creating dist
creating 'dist/django_ratelimit-0.1-py2.7.egg' and adding 'build/bdist.macosx-10.4-x86_64/egg' to it
removing 'build/bdist.macosx-10.4-x86_64/egg' (and everything under it)
Processing django_ratelimit-0.1-py2.7.egg
Copying django_ratelimit-0.1-py2.7.egg to /Users/haoqili/.virtualenvs/playdoh/lib/python2.7/site-packages
Adding django-ratelimit 0.1 to easy-install.pth file

Installed /Users/haoqili/.virtualenvs/playdoh/lib/python2.7/site-packages/django_ratelimit-0.1-py2.7.egg
Processing dependencies for django-ratelimit==0.1
Searching for django
Reading http://pypi.python.org/simple/django/
Reading http://www.djangoproject.com/
Best match: Django 1.3
Downloading http://media.djangoproject.com/releases/1.3/Django-1.3.tar.gz
Processing Django-1.3.tar.gz
Running Django-1.3/setup.py -q bdist_egg --dist-dir /var/folders/yl/yltlIu+3EZy3rSMmgXn6yE+++TI/-Tmp-/easy_install-TVy96n/Django-1.3/egg-dist-tmp-MUK8NL
zip_safe flag not set; analyzing archive contents...
django.conf.__init__: module references __file__
django.conf.project_template.manage: module references __file__
django.contrib.admindocs.views: module references __file__
django.contrib.auth.tests.views: module references __file__
django.contrib.flatpages.tests.csrf: module references __file__
django.contrib.flatpages.tests.middleware: module references __file__
django.contrib.flatpages.tests.templatetags: module references __file__
django.contrib.flatpages.tests.views: module references __file__
django.contrib.formtools.tests.__init__: module references __file__
django.contrib.gis.geometry.test_data: module references __file__
django.contrib.gis.tests.geo3d.tests: module references __file__
django.contrib.gis.tests.geogapp.tests: module references __file__
django.contrib.gis.tests.layermap.tests: module references __file__
django.contrib.sitemaps.tests.basic: module references __file__
django.contrib.staticfiles.storage: module references __file__
django.core.management.__init__: module references __file__
django.core.management.__init__: module references __path__
django.core.management.base: module references __path__
django.core.management.sql: module references __file__
django.core.management.commands.loaddata: module references __file__
django.core.management.commands.loaddata: module references __path__
django.core.management.commands.makemessages: module references __file__
django.core.servers.basehttp: module references __path__
django.db.utils: module references __file__
django.db.models.loading: module references __file__
django.template.loaders.app_directories: module references __file__
django.test._doctest: module references __file__
django.test._doctest: module MAY be using inspect.getsourcefile
django.test.simple: module references __file__
django.utils.autoreload: module references __file__
django.utils.module_loading: module references __path__
django.utils.version: module references __path__
django.utils.translation.__init__: module references __file__
django.utils.translation.trans_real: module references __file__
django.utils.unittest.collector: module references __file__
django.utils.unittest.loader: module references __file__
django.views.i18n: module references __file__
Adding Django 1.3 to easy-install.pth file
Installing django-admin.py script to /Users/haoqili/.virtualenvs/playdoh/bin

Installed /Users/haoqili/.virtualenvs/playdoh/lib/python2.7/site-packages/Django-1.3-py2.7.egg
Finished processing dependencies for django-ratelimit==0.1

Wednesday, June 29, 2011

Getting reCaptcha for django

How I got it to work, in another blog

Things that didn't work:
http://seeknuance.com/2008/03/18/integrating-recaptcha-with-django/

(I tried the other option of http://stackoverflow.com/questions/2275806/easy-to-use-django-captcha-or-registration-app-with-captcha/2275996#2275996  and installed django-registration, but I get a error: "ImportError at /msw/register No module named backends.default")


recaptcha client installation output
recaptcha-client-1.0.6$ python setup.py install
running install
running bdist_egg
running egg_info
writing requirements to recaptcha_client.egg-info/requires.txt
writing recaptcha_client.egg-info/PKG-INFO
writing namespace_packages to recaptcha_client.egg-info/namespace_packages.txt
writing top-level names to recaptcha_client.egg-info/top_level.txt
writing dependency_links to recaptcha_client.egg-info/dependency_links.txt
writing requirements to recaptcha_client.egg-info/requires.txt
writing recaptcha_client.egg-info/PKG-INFO
writing namespace_packages to recaptcha_client.egg-info/namespace_packages.txt
writing top-level names to recaptcha_client.egg-info/top_level.txt
writing dependency_links to recaptcha_client.egg-info/dependency_links.txt
reading manifest file 'recaptcha_client.egg-info/SOURCES.txt'
writing manifest file 'recaptcha_client.egg-info/SOURCES.txt'
installing library code to build/bdist.macosx-10.4-x86_64/egg
running install_lib
running build_py
creating build
creating build/lib
creating build/lib/recaptcha
copying recaptcha/__init__.py -> build/lib/recaptcha
creating build/lib/recaptcha/client
copying recaptcha/client/__init__.py -> build/lib/recaptcha/client
copying recaptcha/client/captcha.py -> build/lib/recaptcha/client
copying recaptcha/client/mailhide.py -> build/lib/recaptcha/client
creating build/bdist.macosx-10.4-x86_64
creating build/bdist.macosx-10.4-x86_64/egg
creating build/bdist.macosx-10.4-x86_64/egg/recaptcha
copying build/lib/recaptcha/__init__.py -> build/bdist.macosx-10.4-x86_64/egg/recaptcha
creating build/bdist.macosx-10.4-x86_64/egg/recaptcha/client
copying build/lib/recaptcha/client/__init__.py -> build/bdist.macosx-10.4-x86_64/egg/recaptcha/client
copying build/lib/recaptcha/client/captcha.py -> build/bdist.macosx-10.4-x86_64/egg/recaptcha/client
copying build/lib/recaptcha/client/mailhide.py -> build/bdist.macosx-10.4-x86_64/egg/recaptcha/client
byte-compiling build/bdist.macosx-10.4-x86_64/egg/recaptcha/__init__.py to __init__.pyc
byte-compiling build/bdist.macosx-10.4-x86_64/egg/recaptcha/client/__init__.py to __init__.pyc
byte-compiling build/bdist.macosx-10.4-x86_64/egg/recaptcha/client/captcha.py to captcha.pyc
byte-compiling build/bdist.macosx-10.4-x86_64/egg/recaptcha/client/mailhide.py to mailhide.pyc
creating build/bdist.macosx-10.4-x86_64/egg/EGG-INFO
copying recaptcha_client.egg-info/PKG-INFO -> build/bdist.macosx-10.4-x86_64/egg/EGG-INFO
copying recaptcha_client.egg-info/SOURCES.txt -> build/bdist.macosx-10.4-x86_64/egg/EGG-INFO
copying recaptcha_client.egg-info/dependency_links.txt -> build/bdist.macosx-10.4-x86_64/egg/EGG-INFO
copying recaptcha_client.egg-info/namespace_packages.txt -> build/bdist.macosx-10.4-x86_64/egg/EGG-INFO
copying recaptcha_client.egg-info/requires.txt -> build/bdist.macosx-10.4-x86_64/egg/EGG-INFO
copying recaptcha_client.egg-info/top_level.txt -> build/bdist.macosx-10.4-x86_64/egg/EGG-INFO
zip_safe flag not set; analyzing archive contents...
creating dist
creating 'dist/recaptcha_client-1.0.6-py2.7.egg' and adding 'build/bdist.macosx-10.4-x86_64/egg' to it
removing 'build/bdist.macosx-10.4-x86_64/egg' (and everything under it)
Processing recaptcha_client-1.0.6-py2.7.egg
Copying recaptcha_client-1.0.6-py2.7.egg to /Users/haoqili/.virtualenvs/playdoh/lib/python2.7/site-packages
Adding recaptcha-client 1.0.6 to easy-install.pth file

Installed /Users/haoqili/.virtualenvs/playdoh/lib/python2.7/site-packages/recaptcha_client-1.0.6-py2.7.egg
Processing dependencies for recaptcha-client==1.0.6
Finished processing dependencies for recaptcha-client==1.0.6

Django UserCreationForm does not save automatically!

If you're not having success in implementing Django's built-in form = UserCreationForm, then you might need to form.save() it:

form = forms.UserCreationForm(data=request.POST)

if form.is_valid():
form.save()

Djnago doesn't save() automatically

Django "accounts/login/?next=..."


I'm in http://127.0.0.1:8000/en-US/msw/login and if login is successful, I make an HttpResponseRedirect() to the front page of my app, "/en-US/msw", but why is redirecting to http://127.0.0.1:8000/en-US/accounts/login/?next=/en-US/msw/ ??  Where does this "accounts/login" and parameter "next" come from? I have never defined them.

solution (thanks to andym and cvan):
"accounts/login" - is set as "LOGIN_URL" in settings.
"next" - is set in src/django/django/contrib/auth/views.py read more about it here.

Django Form not printing out error messages

forms.AuthenticationForm(request.POST) is WRONG, it will not give the wanted error messages (e.g. shown when username and password don't match, when users forget to put in a password).

forms.AuthenticationForm(data=request.POST)


details are highlighted:

[09:38am] haoqili: in python, is it true that if one argument has "name=" in front, the rest of the arguments need to have that too?
[09:38am] haoqili: as in
[09:38am] cvan: no, as long in they are in the correct order
[09:38am] haoqili: "forms.AuthenticationForm(data=request.POST, only_active=True)" is valid
[09:38am] haoqili: oh
[09:38am] cvan: but it is good practice to do that
[09:38am] haoqili: "forms.AuthenticationForm(request.POST, only_active=True)" is not
[09:38am] cvan: so "data=" is not needed
[09:38am] cvan: because it's the first argument
[09:39am] cvan: but it's good practice to either consistenly always used named arguments
[09:39am] cvan: or don't use any names
[09:41am] haoqili: cvan
[09:41am] haoqili: this is really interesting
[09:41am] haoqili: so
[09:41am] haoqili: form = forms.AuthenticationForm(data=request.POST or None, only_active=True)
[09:41am] haoqili: works
[09:42am] haoqili: form = forms.AuthenticationForm(request.POST or None, only_active=True)
[09:42am] haoqili: does not work
[09:42am] haoqili: :P
[09:42am] haoqili: and you are right, "only_active=True" is the culprit
[09:42am] haoqili: :D
[09:43am] cvan: that doesnt make sense if the first works but the second doesnt
[09:44am] cvan: because 'data' is the first argument for forms
[09:44am] cvan: def __init__(self, data=None,
[09:44am] cvan: from the django source for Form
[09:45am] haoqili: hmm
[09:45am] haoqili: that's strange
[09:45am] cvan: are you sure it's not being only_active wasnt True?
[09:45am] cvan: because in what you pasted, only_active is iin both of them
[09:46am] haoqili: oh so the first thing I pasted gives out the intended error messages
[09:46am] haoqili: but the second one was like what we had yesterday, no error messages
[09:46am] haoqili: let me try the 1st one without only_active
[09:47am] haoqili: :O
[09:47am] haoqili: :O
[09:47am] haoqili: So
[09:47am] haoqili: it narrows down to
[09:48am] haoqili: "form = forms.AuthenticationForm(request.POST or None)" does NOT give our wanted error messages
[09:48am] cvan: okay but "only_active" does?
[09:48am] haoqili: "form = forms.AuthenticationForm(data=request.POST or None)" does
[09:48am] haoqili: !!
[09:48am] cvan: weeeird
[09:48am] haoqili: LOL
[09:48am] haoqili: do you want me to come up so you can look more into this?
[09:48am] cvan: because that is the first argument, unless AuthenticationForm does something weird
[09:48am] haoqili: this is sooo strange
[09:48am] cvan: one second let me look at the source for AuthenticationForm again
[09:48am] haoqili: ok
[09:48am] cvan: but stick with "data" named arguments for now, of course
[09:49am] cvan: AAAH
[09:49am] cvan: it's not the first argument for AuthenticationForm
[09:49am] cvan: they override it
[09:49am] haoqili: !!
[09:49am] cvan: that's why!
[09:50am] cvan: silly silly
[09:50am] haoqili: where is this file your looking at?
[09:50am] cvan: because for forms.Form, the first argument is 'data'

# src/django/django/contrib/auth/forms.py line 69

def __init__(self, request=None, *args, **kwargs):

[09:50am] cvan: that's why! request is the first argument for AuthenticationForm
[09:50am] cvan: so as you can see, it really helps to use named arguments ;)
[09:50am] cvan: or just look at the source
[09:51am] cvan: tricky, tricky
[09:51am] haoqili: :O
[09:51am] haoqili: so in the regular "django forms" data is the first argument?
[09:51am] cvan: yep
[09:52am] cvan: but this AuthenticationForm inherits django's Form class
[09:52am] cvan: and extends it
[09:52am] cvan: so that's why it was confusing
[09:53am] haoqili: where is django's Form class?
[09:53am] haoqili: I can't find "from django import forms"
[09:53am] haoqili: oh I found it
[09:54am] cvan: cool

# from src/django/django/forms/forms.py line 72

class BaseForm(StrAndUnicode):
      # This is the main implementation of all the Form logic. Note that this
      # class is different than Form. See the comments by the Form class for more
      # information. Any improvements to the form API should be made to *this*
      # class, not to the Form class.
      def __init__(self, data=None, files=None, auto_id='id_%s', prefix=None,

[09:55am] haoqili: that's the structure that you had in mind, right?
[09:55am] cvan: yep :)
[09:55am] haoqili: I'm so glad we figured this out!!
[09:55am] cvan: yep, good job :)

Tuesday, June 28, 2011

Rate limiting login resourecs

Limit by IP:
- Simple one that limits 20 clicks per IP. I had it running on my xvm.

Django forms

The Django Book's Forms, in preparation of Django Authentication/Login

vendor makes python Django possible

$ python manage.py runserver 8005
Traceback (most recent call last):
File "manage.py", line 5, in
from django.core.management import execute_manager
ImportError: No module named django.core.management

[2:52pm] haoqili: django setup question: why is my "python manage.py runserver" working when I can't "import django" in python?
[2:53pm] wenzel: haoqili: django is part of the vendor/ dir
[2:53pm] wenzel: which is not in Python's standard library path
[2:53pm] haoqili: okay
[2:53pm] wenzel: buuut, manage.py puts it into the library path
[2:53pm] wenzel: edit manage.py and look for site.addsitedir (or something like that)
[2:53pm] jsocol: you can do `python manage.py shell`
[2:53pm] wenzel: that's what puts the vendor/ dir on the list of places where Python looks for imports

Monday, June 27, 2011

Learning Python for Kids

I'd rather have started programming at age 10 than have gone to MIT.

Yes, the best programmers out there are not those who come from the best colleges, but those who started programming in elementary school.

Snake Wrangling for Kids might be the best book you could give your child. Get it here.

Install/Set up Django on Ubuntu

Expanded on this.

1. wget http://www.djangoproject.com/download/1.3/tarball/

2. mv index.html Django-1.3.tar.gz Step 1 downloaded the tar.gz as index.html, so rename it.

3. tar xzvf Django-1.3.tar.gz

4. sudo python setup.py install

Then verify that Django is installed:

5. python

6. import django

7. print django.get_version() should see "1.3", a version number

Yay! All is good.

8. quit()

Sunday, June 26, 2011

Check Mac version on command line

$ system_profiler SPSoftwareDataType

Software:

    System Software Overview:

      System Version: Mac OS X 10.6.7 (10J3331a)
      Kernel Version: Darwin 10.7.3
      Boot Volume: Macintosh HD
      Boot Mode: Normal
      ....

irssi on Mac OS - Failed

1. Downloaded the lastest version of irssi tar gz

2. ./configure --build=x86_64-apple-darwin10.7.3 ARCHFLAGS="-arch x86_64"
*** If you don't have GLIB, you can get it from ftp://ftp.gtk.org/pub/glib/
*** We recommend you get the latest stable GLIB 2 version.
*** Compile and install it, and make sure pkg-config finds it,
*** by adding the path where the .pc file is located to PKG_CONFIG_PATH

configure: error: GLIB is required to build irssi.

3. Get the latest version of GLIB tar gz

4. ./configure --build=x86_64-apple-darwin10.7.3 ARCHFLAGS="-arch x86_64"
configure: error: The pkg-config script could not be found or is too old. Make sure it
is in your PATH or set the PKG_CONFIG environment variable to the full
path to pkg-config.

Alternatively, you may set the environment variables LIBFFI_CFLAGS
and LIBFFI_LIBS to avoid the need to call pkg-config.
See the pkg-config man page for more details.

To get pkg-config, see .
See `config.log' for more details

Get the latest version of pkg-config tar gz, same configure command as before.
configure: error: pkg-config and glib-2.0 not found, please set GLIB_CFLAGS and GLIB_LIBS to the correct values
Yay recursion. :(



Setting up environment variables is so complicated on a Mac.
Gave up.

gdb guide

This is one of the best gdb guides online.

===

For extra debugging, you can set gcc to gcc -g. -- source HtAoE pg 26

Change your personal information (name, identity) on irssi

edit your ~/.irssi/config, it's under
core = {
    real_name = "Your custom name";
    user_name = "Your custom username";
   nick = "Your primary nick";
};

Assembly language angle brackets

The [ebx] in mov eax, [ebx] means that [ebx] is a pointer, kinda like ebx*.
So that line of assembly means move whatever is in the address written in ebx into eax.

... EXCEPT FOR lea

As explained from this assembly guide.
lea — Load effective address
The lea instruction places the address specified by its second operand into the register specified by its first operand. Note, the contents of the memory location are not loaded, only the effective address is computed and placed into the register. This is useful for obtaining a pointer into a memory region.
Syntax
lea <reg32>,<mem>
Examples
lea eax, [var] — the address of var is placed in EAX.
lea edi, [ebx+4*esi] — the quantity EBX+4*ESI is placed in EDI. 

Friday, June 24, 2011

step 3 of check ca chains

Step 3 of a 3 part series. Step 1 and Step 2 will be put up by the end of July 2011.
If you need it sooner, pm me.

------- Step 1: Validating certificate matches url hostname ----

------- Step 2: Verify that the certificate is not expired  --------------

**------- Step 3: Validating the chain of CAs  --------------**

Needs OpenSSL

Needs <a href="https://github.com/haoqili/MozSecWorld/blob/master/apps/msw/files/cacerts.txt">cacerts.txt</a>

Looks long, but actually quite short, just lots of print statements.  Feel free to ask for help! I spent way too long on this. :P


    import socket
    from OpenSSL import SSL

    print "\n------------ Validating the chain of CAs  --------------"
    # crucially MODIFIED from: http://wiki.python.org/moin/SSL
    PORT = 443

    host = "www.google.com" # PUT YOUR HOST NAME HERE
    print "For host = " + str(host)

    # special callback function, cannot change format
    def verify_cb(conn, x509, errno, errdepth, retcode):
        """
        callback for certificate validation
        should return true if verification passes and false otherwise
        """
        print "   CA = " + str( x509.get_subject() )

        if errno == 0:
            if errdepth != 0:
                # don't validate names of root certificates
                print "\t---> GOOD (root certificate)"
                certValid[0] = True
                return True
            else:
                if x509.get_subject().commonName == host:
                    print "\t---> GOOD (cert commonName matched host name)"
                    certValid[0] = True
                    return True
                else:
                    print "\tcertCommonName: \t" + str(x509.get_subject().commonName)
                    print "\thostName: \t\t" + str(host)
                    print "\t---> FAILED (cert commonName did not match host name)"
                    certValid[0] = False
                    return False
        else:
            print "\t---> FAILED"
            certValid[0] = False
            return False

    context = SSL.Context(SSL.SSLv23_METHOD)
    context.set_verify(SSL.VERIFY_PEER | SSL.VERIFY_FAIL_IF_NO_PEER_CERT, verify_cb)
    context.load_verify_locations("cacerts.txt") #or CHANGE TO YOUR CACERTS location!

    # create socket and connect to server
    sock = socket.socket()
    sock = SSL.Connection(context, sock)
    sock.connect((host, PORT))
    try:
        sock.do_handshake()
    except Exception as ec:
        print ec

    print "Disregard if you see 'certificate verify failed' on the line above,
    print "the actual result is below:"

    if certValid[0]:
        print "\r\n Certificate Check: PASSED -- Chain of CAs is VALID"
    else:
        print "\r\n Certificate Check: FAILD -- Chain of CAs is INVALID"

    print "\n------------- End Validating the Certificate of URL = " + str(url) + "\n"



Sample result:



   <!-- language: lang-none -->

    ------------ Validating the chain of CAs  --------------
    For host = www.google.com
       CA = <X509Name object '/C=US/O=VeriSign, Inc./OU=Class 3 Public Primary Certification Authority'>
            ---> GOOD (root certificate)
       CA = <X509Name object '/C=ZA/O=Thawte Consulting (Pty) Ltd./CN=Thawte SGC CA'>
            ---> GOOD (root certificate)
       CA = <X509Name object '/C=US/ST=California/L=Mountain View/O=Google Inc/CN=www.google.com'>
            ---> GOOD (cert commonName matched host name)
    Disregard if you see 'certificate verify failed' on the line above,
    the actual result is below:

     Certificate Check: PASSED -- Chain of CAs is VALID

    ------------- End Validating the Certificate of URL = www.google.com

Django TemplateSyntaxError at /admin/

http://127.0.0.1:8000/en-US/admin/

Django TemplateSyntaxError at /admin/

Caught ViewDoesNotExist while rendering: Tried xxx in module msw.views. Error was: 'module' object has no attribute 'xxx'

Template error

In template /path_to/templates/admin/base.html, error at line ##

...

Traceback Switch to copy-and-paste view

/path_to/vendor/src/django/django/core/handlers/base.py in get_response

The error messages are actually somewhat misleading. The culprit was actually an invalid url in url.py.

Wednesday, June 22, 2011

Monday, June 20, 2011

META http-equiv can only set some HTTP Request Headers

like cache, content-type. more info on Wikipedia.

SSL from terminal

$ openssl s_client -connect sb-ssl.google.com:443

CONNECTED(00000003)

depth=1 C = US, O = Google Inc, CN = Google Internet Authority
verify error:num=20:unable to get local issuer certificate
verify return:0
---
Certificate chain
0 s:/C=US/ST=California/L=Mountain View/O=Google Inc/CN=*.google.com
i:/C=US/O=Google Inc/CN=Google Internet Authority
1 s:/C=US/O=Google Inc/CN=Google Internet Authority
i:/C=US/O=Equifax/OU=Equifax Secure Certificate Authority
---
Server certificate
-----BEGIN CERTIFICATE-----
MIIFCDCCBHGgAwIBAgIKQdyLCwADAAAqyTANBgkqhkiG9w0BAQUFADBGMQswCQYD
VQQGEwJVUzETMBEGA1UEChMKR29vZ2xlIEluYzEiMCAGA1UEAxMZR29vZ2xlIElu
dGVybmV0IEF1dGhvcml0eTAeFw0xMTA1MjcwMTE5MTdaFw0xMjA1MjcwMTI5MTda
MGYxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpDYWxpZm9ybmlhMRYwFAYDVQQHEw1N
b3VudGFpbiBWaWV3MRMwEQYDVQQKEwpHb29nbGUgSW5jMRUwEwYDVQQDFAwqLmdv
b2dsZS5jb20wgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAJcU3tp8DIf+qv8x
WLvWU7NaR8s7kTchk1mM7bLzJgIHsqJlrZeGtbKI+s6SE0nvktjI1qj1rg8J/Gan
Y+F3t2K1hHzGlxeJh9eaMw9N8kCQYWlK6ygl9yScWz+DsI+At6WHRd2VujFB7OF3
e0qUkTiTQnx4Z9hiQeZ4RqBNxjjjAgMBAAGjggLbMIIC1zAdBgNVHQ4EFgQU+R+o
BeihYCVGHnhWUXRm64XwlJowHwYDVR0jBBgwFoAUv8Aw6/VDET5nup6R+/xq2uNr
EiQwWwYDVR0fBFQwUjBQoE6gTIZKaHR0cDovL3d3dy5nc3RhdGljLmNvbS9Hb29n
bGVJbnRlcm5ldEF1dGhvcml0eS9Hb29nbGVJbnRlcm5ldEF1dGhvcml0eS5jcmww
ZgYIKwYBBQUHAQEEWjBYMFYGCCsGAQUFBzAChkpodHRwOi8vd3d3LmdzdGF0aWMu
Y29tL0dvb2dsZUludGVybmV0QXV0aG9yaXR5L0dvb2dsZUludGVybmV0QXV0aG9y
aXR5LmNydDAhBgkrBgEEAYI3FAIEFB4SAFcAZQBiAFMAZQByAHYAZQByMIIBqwYD
VR0RBIIBojCCAZ6CDCouZ29vZ2xlLmNvbYIKZ29vZ2xlLmNvbYILKi5hdGdnbC5j
b22CDSoueW91dHViZS5jb22CC3lvdXR1YmUuY29tggsqLnl0aW1nLmNvbYIPKi5n
b29nbGUuY29tLmJygg4qLmdvb2dsZS5jby5pboILKi5nb29nbGUuZXOCDiouZ29v
Z2xlLmNvLnVrggsqLmdvb2dsZS5jYYILKi5nb29nbGUuZnKCCyouZ29vZ2xlLnB0
ggsqLmdvb2dsZS5pdIILKi5nb29nbGUuZGWCCyouZ29vZ2xlLmNsggsqLmdvb2ds
ZS5wbIILKi5nb29nbGUubmyCDyouZ29vZ2xlLmNvbS5hdYIOKi5nb29nbGUuY28u
anCCCyouZ29vZ2xlLmh1gg8qLmdvb2dsZS5jb20ubXiCDyouZ29vZ2xlLmNvbS5h
coIPKi5nb29nbGUuY29tLmNvgg8qLmdvb2dsZS5jb20udm6CDyouZ29vZ2xlLmNv
bS50coINKi5hbmRyb2lkLmNvbYIUKi5nb29nbGVjb21tZXJjZS5jb20wDQYJKoZI
hvcNAQEFBQADgYEAYTkdKJ+MwKAgzYDiuRsjKJYzmE1W8fx43GQToys/6SC2+jIQ
vPLwQvxj/lN64VEKAkbS/TzVokBgeQtDuGBQUwrjx5MR9X2s0jHakM6ITeH6Zhme
Vhm4ONsoYIWuYHC/JXBVHSa12h96X9a8uwArfAsG1a+RNb4hCczfnIdVbqM=
-----END CERTIFICATE-----
subject=/C=US/ST=California/L=Mountain View/O=Google Inc/CN=*.google.com
issuer=/C=US/O=Google Inc/CN=Google Internet Authority
---
No client certificate CA names sent
---
SSL handshake has read 2279 bytes and written 396 bytes
---
New, TLSv1/SSLv3, Cipher is RC4-SHA
Server public key is 1024 bit
Secure Renegotiation IS supported
Compression: NONE
Expansion: NONE
SSL-Session:
Protocol  : TLSv1
Cipher    : RC4-SHA
Session-ID: 74A3AFC171FDDF82733AAFC7D54B9CF50160DD49FDF95591907339EC96EBE876
Session-ID-ctx:
Master-Key: BA97561FCF6170FEB6B61451ED8DDB6F2E83665399363BA80C64DF4E58A02578EB5C6EF43682EDD77162C985A87DB27D
Key-Arg   : None
PSK identity: None
PSK identity hint: None
TLS session ticket lifetime hint: 100800 (seconds)
TLS session ticket:
0000 - 43 26 be 2d 73 19 df a9-17 64 35 fa 8f 04 73 0b   C&amp;.-s....d5...s.
0010 - d9 41 aa 6d 6a d3 6b 7e-d3 b5 f7 ec 92 c1 fb dd   .A.mj.k~........
0020 - 94 c2 73 d3 ab 6e c0 da-5d 20 0d 07 dc 08 87 4e   ..s..n..] .....N
0030 - 7c b5 f1 26 1f 08 73 2b-19 9e 83 ba 15 a4 80 f1   |..&amp;..s+........
0040 - 60 c7 95 aa 74 f7 f2 f0-47 db ea d8 0a 34 33 2a   `...t...G....43*
0050 - d9 68 68 cb 53 6e a2 33-5a 54 46 c1 3c 86 2c e9   .hh.Sn.3ZTF.&lt;.,.
0060 - 6c 54 5f 1d ce 8b c9 6d-79 74 5d af fd d2 06 7d   lT_....myt]....}
0070 - a8 80 d1 00 53 44 dd a2-5b ef 75 5a bd 32 60 69   ....SD..[.uZ.2`i
0080 - b0 2e 50 12 bd ed c8 dc-c8 28 70 e2 44 9d c0 6e   ..P......(p.D..n
0090 - 66 fd 5b 25                                       f.[%

Start Time: 1308355198
Timeout   : 300 (sec)
Verify return code: 20 (unable to get local issuer certificate)
---


read:errno=0

Vim delete from curser to line number

The command in Vim to delete from the current position of the curser to a greater line number, 57 for example, is

:,57d

This is derived from deleting lines in a range, lines 22 to 57 for example:
:22,57d

CSS bullets click on entire row

Click on entire row for list bullets:

li a {
    display: block;
}

Make url underline disappear in css

Make url underline disappear in CSS, no url underline anymore:

a {
    text-decoration: none;
}

Make list bullets disappear in CSS

Make list bullets disappear, in CSS:

li {
    list-style: none;
}

Friday, June 17, 2011

Python Webserver Checking SSL Certificates

Python Urllib and Urllib2 have warnings that say:
"Warning: When opening HTTPS URLs, it is not attempted to validate the server certificate. Use at your own risk!"



Add SSL-cert-check thing: `pip install backports.ssl_match_hostname` ... because Django/Python's urllib's urlopen does not check the SSL server certificates [warning on urllib documentation](http://docs.python.org/library/urllib.html), thus becoming vulnerable to Man-In-The-Middle attacks. [Solution source](http://stackoverflow.com/questions/1087227/validate-ssl-certificates-with-python/3946778#3946778)
http://wiki.python.org/moin/Twisted-Examples
--> Twisted, PyOpenSSL, Pycrypto
`svn co svn://svn.twistedmatrix.com/svn/Twisted/trunk`
`cd trunk`
`python setup.py install`

`pip install pyopenssl`

`python setup.py install`

Check in python shell: `import twisted, OpenSSL, Crypto`

Wednesday, June 15, 2011

Getting SSL Certificate Checking to work

Workon playdoh
In directory CheckSSLCert

1. Install Twisted
1.1- svn co svn://svn.twistedmatrix.com/svn/Twisted/trunk
1.2- cd trunk
1.3- python setup.py install

check on chunk of code-

2. Install pyOpenSSL: pip install pyopenssl
2.1- Download the tar.gz http://launchpad.net/pyopenssl/main/0.11/+download/pyOpenSSL-0.11.tar.gz to directory
2.2a- ./Configure darwin64-x86_64-cc
- make

"_ENGINE_load_gost", referenced from:
_ENGINE_load_builtin_engines in libcrypto.a(eng_all.o)
ld: symbol(s) not found
collect2: ld returned 1 exit status
make[2]: *** [link_app.] Error 1
make[1]: *** [openssl] Error 2
make: *** [build_apps] Error 1
2.2b- ./Configure darwin64-x86_64-cc zlib no-asm no-krb5 shared
- make

ld: duplicate symbol _OPENSSL_cleanse in libcrypto.a(mem_clr.o) and libcrypto.a(x86_64cpuid.o)
collect2: ld returned 1 exit status
make[4]: *** [link_a.darwin] Error 1
make[3]: *** [do_darwin-shared] Error 2
make[2]: *** [libcrypto.1.0.0.dylib] Error 2
make[1]: *** [shared] Error 2
make: *** [build_crypto] Error 1
- ld: in ../libcrypto.a(XT), archive member 'XT' with length 0 is not mach-o or bitcode
collect2: ld returned 1 exit status
make[2]: *** [link_app.] Error 1
make[1]: *** [openssl] Error 2
make: *** [build_apps] Error 1
2.2c - Try again: ./Configure darwin64-x86_64-cc - make



3. Install PyCrypto tar.gz
- python setup.py install


Check that things got installed properly in Python shell
- import twisted, OpenSSL, Crypto

Tuesday, June 14, 2011

Firebug Failed to show POST Response

For future reference, showing errors with GET:

            var fields = {
                    'client': client,
                    'apikey': apikey,
                    'appver': appver,
                    'pver': pver,
                    'url': 'http://www.phishing.com/'
            };
            $.ajax({
                    url: 'https://sb-ssl.google.com/safebrowsing/api/lookup',
                    type: 'GET',
                    data: fields,
                    dataType: "text",
                    success: function(rdata) {
                            $('#gdb').html(rdata);
                    },
                    error: function() {
                            // Handle errors
                    }
            }); 

Google Safe Browsing API

1. Chose to use the simpler "Safe Browsing Lookup API" instead of the more complicated "Safe Browsing API v2". Comparison between the two.
    - Found a Python library to look up Google's Safe Browsing API, with Django as well, but it has not been updated for over a year and it does not use "Safe Browsing Lookup API".

Django objects.all() reverse or descending order

objects.all().order_by('-id') ... or negative whatever the field name is.

I don't know why this didn't work for me: objects.all().reverse()

Tutorial: Make Ajax Form in Django + Bleach Sanitization on Playdoh + Jingo + Jinja

You can see the final version of complete files here.


1. Import bleach.

2. Make a new (dummy) url
2: in urls.py
(r'^richtext$', 'richtext'),

3. models.py: Make a new model. Go to SQL to add some initial entries into the model.

My model, RichText, looks like this:
3: in models.py:
from django.db import models
class RichText(models.Model):
    name = models.CharField(max_length=200)
    comment = models.TextField()

4. models.py: Make a form associated with that model, it's a Django ModelForm.

5. models.py: Clean the commented data through bleach.clean()


5a. clean_<fieldname>(): Note that the method name "clean_comment" is not chosen arbitrarily. It must start with "clean_" and the 2nd part must match with one of the fields of the model.


5b. cleaned_data[]: is like POST[] or REQUST[], but with cleaned_data, the "data has not only been validated but will also be converted in to the relevant Python types".

5c. Finally do a bleach.clean on the data before it's returned.

4+5: in models.py:
from django.forms import ModelForm
class RichTextForm(ModelForm):
    class Meta:
        model = RichText

    def clean_comment(self): #comment must match one of the fields of model
        data = self.cleaned_data['comment']
        return bleach.clean(data)

6. richtext.html: Make the Django form's html
<form id="myform" action="" method="post">
    {{ csrf() }}
    {{ form.as_p() }}
<input type="submit" value="Submit" />
</form>

You might get an CRSF error at this point... keep reading

Note that the "CSRF()" is different from how Django usually contains it, it's explained here and in the flip below:.
CSRF Explanation
Django's fix to CSRF can be found in [https://docs.djangoproject.com/en/dev/intro/tutorial04/ the tutorial]. Where you put in

template.html:
{% csrf_token %}

views.py:
from django.shortcuts import render_to_response
from django.template import RequestContext
def ...
    return render_to_response('template.html', {'var_name': var_value}, context_instance=RequestContext(request))

But in the demo's setup with jingo and other stuff:
template.html:
{{ csrf() }}
views.py:
import jingo
    return jingo.render(request, 'template.html', {"var_name": var_value})

7. richtext.html: add AJAX to submit form and display all results
<script src="http://code.jquery.com/jquery-latest.min.js" type="text/javascript">
</script>
    <div id="results">
    {% include 'msw/richtext_table.html' %}
</div>
    <script>
        $("#myform").submit(function(){
            $.post(location.href, $('#myform').serialize(), function(d) {
$('#results').html(d);   
});
            return false;
        })
    </script>

If the HTML is not rendered, use "|safe".
richtext_table.html:
    {% if all_richtext_list %}
        {% for richtext in all_richtext_list %}
            <p>Name title: <b>{{ richtext.name|safe }}</b> says: <b>{{ richtext.comment|safe }}</b></p>
        {% endfor %}
    {% else %}
        <p>No comments are available.</p>
    {% endif %}

8. views.py: Save new Django AJAX form inputs

NOTE: There are 2 different template filenames. The "_table.html" is there so that whenever there is a post, ONLY the output table is rendered. Without that line, the entire page would be rendered!!

import bleach
from msw.models import RichText, RichTextForm
...

def richtext(request):
    file = 'msw/richtext.html'
    if request.method == "POST":
        form = RichTextForm(request.POST)
        if form.is_valid():
            form.save()
        file = 'msw/richtext_table.html'
    else:
        form = RichTextForm()
    return jingo.render(request, file, {"form": form, "title_chunk" : "Bleach Testing:", "all_richtext_list": RichText.objects.all()})


You can see the final version of complete files here.

Monday, June 13, 2011

News Forum Rich Text Sanitizing with Bleach

Bleach github
       - Is bleach already in django?
       - Example of bleach
- Make a news forum


Bleach
- Get the bleach module


(playdoh)haoqili@host-3-248:11:50:59:~/dev/playdoh/playdoh/playdoh$ ./manage.py shell
Python 2.7.1 (r271:86832, Jun  6 2011, 13:57:48)
[GCC 4.2.1 (Apple Inc. build 5666) (dot 3)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
(InteractiveConsole)
>>> import bleach
Traceback (most recent call last):
  File "<console>", line 1, in <module>
ImportError: No module named bleach
>>>
KeyboardInterrupt
>>>
(playdoh)haoqili@host-3-248:12:00:06:~/dev/playdoh/playdoh/playdoh$ pip install -e git://github.com/jsocol/bleach.git#egg=bleach
Obtaining bleach from git+git://github.com/jsocol/bleach.git#egg=bleach
  Cloning git://github.com/jsocol/bleach.git to /Users/haoqili/.virtualenvs/playdoh/src/bleach
  Running setup.py egg_info for package bleach
   
Downloading/unpacking html5lib (from bleach)
  Downloading html5lib-0.90.zip (99Kb): 99Kb downloaded
  Running setup.py egg_info for package html5lib
   
Installing collected packages: bleach, html5lib
  Running setup.py develop for bleach
   
    Creating /Users/haoqili/.virtualenvs/playdoh/lib/python2.7/site-packages/bleach.egg-link (link to .)
    Adding bleach 1.0.2 to easy-install.pth file
   
    Installed /Users/haoqili/.virtualenvs/playdoh/src/bleach
  Running setup.py install for html5lib
   
Successfully installed bleach html5lib
Cleaning up...
(playdoh)haoqili@host-3-248:12:00:54:~/dev/playdoh/playdoh/playdoh$ ./manage.py shellPython 2.7.1 (r271:86832, Jun  6 2011, 13:57:48)
[GCC 4.2.1 (Apple Inc. build 5666) (dot 3)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
(InteractiveConsole)
>>> import bleach
>>> bleach.clean('an <script>evil()</script> example')
u'an &lt;script&gt;evil()&lt;/script&gt; example'
>>> bleach.linkify('an http://example.com url')
u'an <a href="http://example.com" rel="nofollow">http://example.com</a> url'

==========
jsocol: the "u" indicates that it's a unicode string instead of a simple bytestring, it's a python thing
==========

jsocol: haoqili: there's no Bleach() class anymore, it's just "import bleach" or "from bleach import clean, linkify"









haoqili: I'm looking at __init__.py
[12:25pm] jsocol: ok
[12:25pm] haoqili: What is the significance of TLDS = """ac ad ae aero af ag ai al am an ao aq ar arpa as asia at au aw ax az
[12:25pm] haoqili: ba bb bd be bf bg bh bi biz bj bm bn bo br bs bt bv bw by bz ca cat?
[12:25pm] haoqili: i.e. what is TLDS?
[12:26pm] jsocol: TLD = Top Level Domain, it's supposed to be an exhaustive list of all the current, valid TLDs
[12:26pm] jsocol: so that, for example, "example.com" or "example.co.uk" gets linkified, but "example.txt" does not
[12:26pm] haoqili: ah
[12:26pm] haoqili: okay
[12:27pm] haoqili: I'm also trying to understand how clean's ALLOWED_TAGS get added to the pre-defined ALLOWED_TAGS
[12:28pm] haoqili: is it added or replaced?
[12:28pm] haoqili: I guess it's replaced?
[12:28pm] jsocol: replaced. if you pass in a tags= kwarg, your list supercedes the default list, so you can be more restrictive

Server Certificate stuff for SSL

Playdoh/Django server setup doc:
docs/operations.rst:Apps are typically run under Apache and mod_wsgi in production. Entry point: wsgi/playdoh.wsgi

Got openssl, I found the executable openssl in /usr/local/ssl/bin. And replaced the old openssl in /usr/bin with it.

Followed this for setting up (copied below in flip panel) a certificate:


Generating a Private Key and CSR
    $ openssl genrsa -des3 -out server.key 1024
    $ openssl rsa -in server.key -out server.pem
    $ openssl req -new -key server.key -out server.csr

Generating a Self-Signed Certificate
    $ openssl x509 -req -days 120 -in server.csr -signkey server.key -out server.crt

vendor/src/django/docs/howto/apache-auth.txt

Support for mod_python has been deprecated within Django. At that time, this method of authentication will no longer be provided by Django. The community is welcome to offer its own alternate solutions using WSGI middleware or other approaches.



vendor/src/django/docs/topics/install.txt. and Django with wsgi


me: It's a wsgi server
super: isn't wsgi a mod to allow django to work with apache?
me: I'll google about it
super: i'm pretty sure it is. if so, then you can just do the cert install per normal apache process
...
...
me: I'm failing to find some files: apache/etc/ssl.conf and httpd.conf
Do you know where they are?
super: normally i believe they are in /etc
me: are they supposed to be on my local machine ... not on playdoh?
super: it is installed by playdoh
*came to desk and did the following:*

$ ps -a
  704 ttys000    0:56.66 /Users/haoqili/.virtualenvs/playdoh/bin/python ./manage.py runserver

This is Django's bulit-in web server :(

:( have to install Apache. --> put off till later --> ask webdev people

Do it later.

click here for a copy of slacksite's ssl certificate

Generating a Private Key and CSR

The openssl toolkit is used to generate an RSA Private Key and CSR (Certificate Signing Request). It can also be used to generate self-signed certificates which can be used for testing purposes or internal usage. The utility used to do all of these tasks is known simply as openssl. It should be installed in the /usr/local/ssl/bin directory. You may want to add this directory to your PATH, or copy or link the openssl utility to a directory that is already in your PATH so that you do not have to type the full path to the executable. The examples below will assume that opensslis in a location that is accessible to you without using the full path to the command.
The first step is to create your RSA Private Key. This key is a 1024 bit RSA key which is encrypted using Triple-DES and stored in a PEM format so that it is readable as ASCII text. We will use several files as random seed enhancers which will help to make the key more secure. Text files that have been compressed with a utility such as gzip are good choices. The key is generated using the following command, where file1:file2:etc represents the random compressed files.
$ openssl genrsa -des3 -rand file1:file2:file3:file4:file5 -out server.key 1024
The command will prompt you for a pass-phrase and then store the key in the file server.keyIt is critical that the pass-phrase be secure and not forgotten. If either the key is lost, or the pass-phrase is forgotten, the certificate will be useless! It cannot be stressed enough how important the private key is to the certificate. If the private key and pass-phrase are compromised, the certificate will have to be revoked, costing you the price of the certificate all over again if you have paid an authority for the certificate. It may be a wise idea to back this file up to secure media, such as tape or diskette.
One unfortunate side-effect of the pass-phrased private key is that Apache will ask for the pass-phrase each time the web server is started. Obviously this is not necessarily convenient as someone will not always be around to type in the pass-phrase, such as after a reboot or crash. mod_ssl includes the ability to use an external program in place of the built-in pass-phrase dialog, however, this is not necessarily the most secure option either. It is possible to remove the Triple-DES encryption from the key, thereby no longer needing to type in a pass-phrase. If the private key is no longer encrypted, it is critical that this file only be readable by the root user! If your system is ever compromised and a third party obtains your unencrypted private key, the corresponding certificate will need to be revoked. With that being said, use the following command to remove the pass-phrase from the key:
$ openssl rsa -in server.key -out server.pem
Once the private key is generated a Certificate Signing Request can be generated. The CSR is then used in one of two ways. Ideally, the CSR will be sent to a Certificate Authority, such asThawte or Verisign who will verify the identity of the requestor and issue a signed certificate. The second option is to self-sign the CSR, which will be demonstrated in the next section.
During the generation of the CSR, you will be prompted for several pieces of information. These are the X.509 attributes of the certificate. One of the prompts will be for "Common Name (e.g., YOUR name)". It is important that this field be filled in with the fully qualified domain name of the server to be protected by SSL. If the website to be protected will be https://www.server.com, then enter www.server.com at this prompt. The command to generate the CSR is as follows:
$ openssl req -new -key server.key -out server.csr
A sample CSR generation session is shown below, with sample responses shown in bold:
$ openssl req -new -key server.key -out server.csr
Using configuration from /usr/local/ssl/openssl.cnf
Enter PEM pass phrase:Enter pass phrase here
You are about to be asked to enter information that will be incorporated into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN. There are quite a few fields but you can leave some blank.
For some fields there will be a default value, If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [AU]:US
State or Province Name (full name) [Some-State]:New Hampshire
Locality Name (eg, city) []:Nashua
Organization Name (eg, company) [Internet Widgits Pty Ltd]:Domain.com, Inc.
Organizational Unit Name (eg, section) []:.

Common Name (eg, YOUR name) []:www.domain.com
Email Address []:webmaster@domain.com


Please enter the following 'extra' attributes to be sent with your certificate request
A challenge password []:
An optional company name []:


Generating a Self-Signed Certificate

At this point you will need to generate a self-signed certificate because you either don't plan on having your certificate signed by a CA, or you wish to test your new SSL implementation while the CA is signing your certificate. In my experience dealing with Thawte, it can take up to a week or more before receiving your signed certificate. The time it takes to receive the certificate will vary based on how quickly they receive your required documentation. This temporary certificate will generate an error in the client browser to the effect that the signing certificate authority is unknown and not trusted.
To generate a temporary certificate which is good for 60 days, issue the following command:
$ openssl x509 -req -days 60 -in server.csr -signkey server.key -out server.crt


Installing the Private Key and Certificate

When Apache with mod_ssl is installed, it creates several directories in the Apache config directory. The location of this directory will differ depending on how Apache was compiled. If using my instructions on compiling Apache, the config directory is /usr/local/apache/etc. The directories mod_ssl creates include ssl.crtssl.csr, and ssl.key. These are good locations to store server certificates, CSRs, and private keys, respectively. If there will be multiple SSL enabled hosts on one server, it may be good practice to name the files with the fully qualified domain name of the SSL enabled host.
When adding SSL enabled virtualhosts to the web server, I prefer to keep all of the SSL virtualhosts in a separate file. This insures that all SSL hosts can be easily found in one location and helps to keep the httpd.conf file from growing too large. The SSL virtualhosts will be kept in a file called ssl.conf. In order for Apache to recognize and parse this file, it must be included in the httpd.conf file with the following directive:
Include /usr/local/apache/etc/ssl.conf


Configuring SSL Enabled Virtual Hosts

Extensive examples of SSL configurations for a virtualhost are included as part of the/usr/local/apache/etc/httpd.conf.default file installed with mod_ssl. Please refer to this file and to the mod_ssl documentation for more detailed information on configuration options. A basic SSL enabled virtualhost will appear as follows in the ssl.conf file:
# SSL Virtual Hosts
<IfDefine SSL>

<VirtualHost _default_:443>
ServerAdmin webmaster@domain.com
DocumentRoot /usr/local/apache/share/htdocs
ServerName www.domain.com
ScriptAlias /cgi-bin/ /usr/local/apache/share/htdocs/cgi-bin/
SSLEngine on
SSLCertificateFile /usr/local/apache/etc/ssl.crt/server.crt
SSLCertificateKeyFile /usr/local/apache/etc/ssl.key/server.pem
SetEnvIf User-Agent ".*MSIE.*" nokeepalive ssl-unclean-shutdown
CustomLog /usr/local/apache/var/log/ssl_request_log \"%t %h %{SSL_PROTOCOL}x %{SSL_CIPHER}x \"%r\" %b" </VirtualHost>

</IfDefine>
This will create an SSL virtualhost named www.domain.com, which is accessed via port 443 (the standard port for https) on the default IP address of the web server. It is possible to add as many additional virtualhosts as there are IP addresses that the web server listens to. Simply add additional virtualhost blocks inside of the <IfDefine SSL> and </IfDefine> tags. Due to the nature of the SSL encryption of the HTTP traffic, it is NOT possible to have name-based (HTTP1.1) SSL virtual hosts. To create a new SSL virtualhost on a different IP address, simply replace _default_ with the IP address of the virtualhost.
After adding the virtualhost to the ssl.conf file, Apache must be killed and restarted in order for it to recognize the new virtualhost. Unfortunately, this is one of the rare instances where a simpleHUP signal will not work. After restarting the server, depending on whether the encrypted or unencrypted key was used, Apache will prompt you for the pass-phrase(s) of the SSL virtualhost(s). Enter the pass-phrase(s) and the web server will start.
Now, point your favorite browser to the new virtualhost you just created, remembering to use https:// instead of http://, and you should be greeted with a warning dialog if you are using the self-signed certificate. Acknowledge the dialog and the page will continue to load, protected by SSL. The status bar of your browser should be graced by the 'lock' icon, which signifies the page is protected via SSL. This is all there is to it!