added 2008 and some 2009
[amrad.git] / accounts.cgi
1 #!/usr/bin/python
2 #
3 # HTML user database handler for account requests
4 print "Content-Type: text/html"
5
6 import pickle,string,os,sys,re,time,urllib,cgi,md5,sha,crypt, random, string, smtplib
7 # authlib
8
9 def getsalt(chars = string.letters + string.digits):
10     # generate a random 2-character 'salt'
11     return random.choice(chars) + random.choice(chars)
12
13 # Secret credentials like: "dbname=DATABSE user=DBUSER host=localhost password=XXXXXXXX requiressl=1"
14 # DSN = pickle.load(open('/srv/sites/dsn-request.p'))
15 DSN = "DSN"
16
17 def send_valid_application(mssg):
18         smtpserver = 'atanasoff.rf.org'
19         AUTHREQUIRED = 0 # if you need to use SMTP AUTH set to 1
20         smtpuser = ''  # for SMTP AUTH, set SMTP username here
21         smtppass = ''  # for SMTP AUTH, set SMTP password here
22         
23         RECIPIENTS = ['mb@rf.org']
24         SENDER = 'webmaster@amrad.org'
25         #mssg = open('mssg.txt', 'r').read()
26         fullmssg = "From: Account Form <webmaster@amrad.org>\nTo: Maitland <aa4hs@amrad.org>\nSubject: AMRAD Server Account request\n\n"+ mssg
27         
28         session = smtplib.SMTP(smtpserver)
29         if AUTHREQUIRED:
30                 session.login(smtpuser, smtppass)
31         smtpresult = session.sendmail(SENDER, RECIPIENTS, fullmssg)
32
33 def bad_send_smtpresult_handling():     
34         if smtpresult:
35                 errstr = ""
36                 for recip in smtpresult.keys():
37                         errstr = """Could not deliver mail to: %s
38         
39         Server said: %s
40         %s
41         
42         %s""" % (recip, smtpresult[recip][0], smtpresult[recip][1], errstr)
43                 raise smtplib.SMTPException, errstr
44
45 def log_valid_application_orig(DSN,form):
46         """Log submitted values to the database for review by the administrator.
47
48         The database schema needs to support this function, and the values are
49         pulled from the environment and a passed cgi form object
50         """
51         sha_pw = sha.new()
52         sha_pw.update(form.getvalue('password'))
53         md5_pw = md5.new()
54         md5_pw.update(form.getvalue('password'))
55         pwcrypt = crypt.crypt(form.getvalue('password'), getsalt())
56         #md5crypt = authlib.passcrypt(form.getvalue('password'), None, 'md5', '$1$')
57         #conn = psycopg.connect(DSN)
58         #curs = conn.cursor()
59         message = "INSERT INTO account_requests (usename,fullname,pwsha,pwmd5,pwcrypt,notes,reqtime,ipaddr,ssl_verify,client_s_dn,client_i_dn,client_s_dn_cn) VALUES (%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s);" % (form.getvalue('username'), form.getvalue('Fullname'), sha_pw.hexdigest(), md5_pw.hexdigest(), pwcrypt, form.getvalue('password'), form.getvalue('comment'), time.ctime(), os.environ['REMOTE_ADDR'], os.environ['SSL_CLIENT_VERIFY'], os.getenv('SSL_CLIENT_S_DN'), os.getenv('SSL_CLIENT_I_DN'), os.getenv('SSL_CLIENT_S_DN_CN'))
60         #message += "\n\nOr paste\n{crypt}%s\n into luma new password dialog box with cleartext hash algorithm.\n" % (md5crypt)
61         send_valid_application(message)
62
63 def log_valid_application(DSN,form):
64         """Log submitted values to the database for review by the administrator.
65
66         The database schema needs to support this function, and the values are
67         pulled from the environment and a passed cgi form object
68         """
69         #message = "Test"
70         message = "INSERT INTO account_requests (usename,fullname,password,notes,reqtime,ipaddr,ssl_verify,client_s_dn,client_i_dn,client_s_dn_cn) VALUES (%s,%s,%s,%s,%s,%s);" % (form.getvalue('username'), form.getvalue('Fullname'), form.getvalue('password'), form.getvalue('comment'), time.ctime(), os.environ['REMOTE_ADDR'])
71         htpasswd_cmd = 'htpasswd -nb -s %s %s' % (form.getvalue('username'), form.getvalue('password'))
72         htpasswd_line = os.popen(htpasswd_cmd).readline()
73         print '<pre>%s</pre>' % (htpasswd_line)
74         message += htpasswd_line
75         send_valid_application(message)
76
77 print """
78
79 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"><html><head><meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"><title>Account Request</title><meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1"><style type="text/css" media="all" title="Fancy Page Style">
80      @import url(/index.css);
81     </style></head>
82 <body>
83 <div id="header"><b>Amateur Radio Research and Development Corporation</b>
84 <br>Post Office Drawer 6148, McLean, Virginia 22106-6148, USA
85 <br><i>Amateur Radio experimenters specializing in telecommunications technology</i></div>
86
87 <div id="content">
88     <h1>Server account request form</h1>
89         For new requests, or forgotten passwords.
90 """
91
92 if ("GET" == os.environ["REQUEST_METHOD"]):
93         print """
94 <div>
95 <FORM METHOD=POST ACTION="https://amrad.org/accounts.cgi">
96 <hr>Fill out the form in the following section, then submit
97         using the <em>Submit Your Request</em> button below.<p>
98
99   <table CELLPADDING="4" WIDTH="100%" CELLSPACING="3" style="color:black">
100     <tr>
101       <td><center><strong>Description</strong></center></td>
102       <td><center><strong>Value</strong></center></td>
103     </tr>
104     <tr>
105       <td COLSPAN="2"><center><em>Account settings</em></center></td>
106     </tr>
107
108         <tr>
109       <td BGCOLOR="#dddddd"><div align="right">Username</div></td>
110       <td BGCOLOR="#dddddd"><INPUT TYPE=TEXT NAME=username SIZE=20 MAXLENGTH=32></td>
111         </tr>
112
113         <tr>
114       <td BGCOLOR="#dddddd"><div align="right">Password<br>(8 character minimum)</div></td>
115       <td BGCOLOR="#dddddd"><INPUT TYPE=PASSWORD NAME=password SIZE=32 MAXLENGTH=64></td>
116         </tr>
117
118         <tr>
119       <td BGCOLOR="#dddddd"><div align="right">Password<br>(again to check your typing)</div></td>
120       <td BGCOLOR="#dddddd"><INPUT TYPE=PASSWORD NAME=pwcheck SIZE=32 MAXLENGTH=64></td>
121         </tr>
122
123     <tr>
124       <td COLSPAN="2"><center><em>Additional user information</em></center></td>
125     </tr>
126
127         <tr>
128       <td BGCOLOR="#dddddd"><div align="right">Full name.</div></td>
129       <td BGCOLOR="#dddddd"><INPUT TYPE=TEXT NAME=Fullname SIZE=32 MAXLENGTH=64></td>
130         </tr>
131
132         <tr>
133       <td BGCOLOR="#dddddd"><div align="right">Email address</div></td>
134       <td BGCOLOR="#dddddd"><INPUT TYPE=TEXT NAME=email SIZE=32 MAXLENGTH=64></td>
135         </tr>
136
137         <tr>
138       <td BGCOLOR="#dddddd"><div align="right">Notes.<br>Additional information to help the administrator<br>(phone numbers, employer, mailing address...)</div></td>
139       <td BGCOLOR="#dddddd"><TEXTAREA NAME=comment COLS=64 ROWS=10></TEXTAREA></td>
140         </tr>
141
142     <tr>
143
144       <td COLSPAN="2"><br></td>
145     </tr>
146   </table>
147 <center>
148   <table CELLPADDING="2" CELLSPACING="0" BORDER="0">
149     <tr>
150       <td ALIGN="middle"><strong><INPUT name="submit" type="SUBMIT" value="Submit Your Request" ></strong></td>
151     </tr>
152   </table>
153
154 </center>
155 </FORM>
156 </div>
157         """
158         print "<BR>"
159 #       for k,v in os.environ.items():
160 #               print k, v, "<br>"
161 else:
162         form = cgi.FieldStorage(keep_blank_values=1)
163         if ('Submit Your Request' == form.getvalue('submit')):
164                 try:
165                         if (( form.getvalue('password') == form.getvalue('pwcheck') ) and (len(form.getvalue('password')) >7)):
166                                 print '<div><hr>If everything looks OK, submit using the <em>Verify Your Request</em> button below.<p>'
167                                 print '<FORM METHOD=POST ACTION="https://amrad.org/accounts.cgi">'
168                                 print "New account request for:", form.getvalue('username'), "<br>"
169                                 print form.getvalue('Fullname')
170                                 print '&lt;%s&gt;<br>' % (form.getvalue('email'))
171                                 print form.getvalue('comment'), "<br>"
172                                 print '<input type="hidden" name="username" value="%s">' % (form.getvalue('username'))
173                                 print '<INPUT name="submit" type="SUBMIT" value="Verify Your Request" ></FORM></div>'
174                                 log_valid_application(DSN,form)
175                         else:
176                                 print "Bad Password, try again<BR>"
177                                 if (len(form.getvalue('password')) <8):
178                                         print "(use a longer password)<br>"
179                                 if ( form.getvalue('password') != form.getvalue('pwcheck')):
180                                         print "(type more carefully next time)<br>"
181                 except:
182                         print "Bad input, try again"
183         elif ('Verify Your Request' == form.getvalue('submit')):
184                 print 'Your request for user %s' % (form.getvalue('username'))
185                 print "was submitted at", time.ctime(),"<BR>"
186         else:
187                 print "Problem - no submission"
188
189 print """
190 </div>
191
192 <address>Contact: <a href="mailto:webmaster@amrad.org">webmaster</a></address>
193 </body></html>
194 """