Archive for the ‘Coding’ CategoryA friend of mine passed over the following blog entry, which I found quite to my liking. J.P. Boodhoo (a leader in the .Net development community) has found some plugins and tools which enable vim in certain applications in Windows. Those being:
Check out the article. It’s awesome. One of my friends who has used PHP in the past, but hasn’t touched it in a while, recently asked me what the best was to handle mass edits and deletions on a page. To understand more what he’s talking about, he has a form with a table of data, each containing checkboxes in a column labeled as Delete? He wants to know how he should handle the deleting multiple rows in a fast and efficient way. How it may have been done (and you may be doing it right now) might look like this: <form action="deleteCategories.php" method="post"> <input type="checkbox" name="deleteCategory1" /> Category 1<br /> <input type="checkbox" name="deleteCategory2" /> Category 2<br /> <input type="checkbox" name="deleteCategory3" /> Category 3<br /> </form>
The above code is highly inefficient, and if you’re dealing with database records, I honestly don’t see how your application would survive. You would have to add lines to deal with other records, which would make your application severely crippled, or extremely difficult to maintain - one of the two. The solution to this is simple: use an “HTML Array”. When I say this, some people who have spent their lives working in HTML are going to say that HTML doesn’t have arrays. Of course they don’t. It’s PHP, though, that does. However, you have to pass to PHP the “array” in a certain fashion so that when it loads up it’s scripts, it knows its an array. Here’s how it works. In PHP, arrays are usually written to and read from like this:
So, in HTML, how on earth do you do arrays? You don’t have an <form action="deleteCategories.php" method="post"> <input type="checkbox" name="delete[category][]" value="1" />Category 1<br /> <input type="checkbox" name="delete[category][]" value="2" />Category 2<br /> <input type="checkbox" name="delete[category][]" value="3" />Category 3<br /> </form> What you see is I’ve named the checkbox fields the same name. In normal HTML land, this would be a no-no, and there’s a way to get around it if it doesn’t validate. That is, you simply switch to the following: <form action="deleteCategories.php" method="post"> <input type="checkbox" name="delete[category][1]" />Category 1<br /> <input type="checkbox" name="delete[category][2]" />Category 2<br /> <input type="checkbox" name="delete[category][3]" />Category 3<br /> </form> Now each checkbox has it’s own name and doesn’t overlap with others. We’ll consider the first HTML set case 1 and the second case 2. Here’s where the true PHP “magic” takes over and makes this a really powerful solution. You don’t have to then check and delete with the following code:
The above code is horrible. If you’re currently writing code like that above, slap yourself in the face with a nice wet fish. You’re about to get a rude awakening. Here’s how you’re actually going to use it:
In either case, only the checkboxes that are selected come through as the array, but in either case, PHP converts what looks like a name with special characters in HTML to an actual PHP array. It’s very powerful and you can script code to handle what you need to and not have to worry about adding or changing it as your database grows. BackgroundWell, as many of you have known, I’ve been working on projects that involve the dark side - that being Microsoft projects. Yes, this means I’ve been working on .Net applications in both Visual Basic and C#. The C# applications are kinda fun to work with, but I still maintain that VB is a ridiculous language, despite the fact that both VB and C# compile to the same intermediate code. In any case, I’ve been working on a legacy application that uses Crystal Reports to handle it’s reporting. For anyone looking for an opinion on Crystal Reports - don’t get it and don’t even think about touching it with a 10 foot pole. It’s nasty, bulky, and extremely difficult to install and configure with applications appropriately. This is the whole purpose of this post. EnvironmentThis application is being run on a Windows Server 2003 w/ Service Pack 2 server behind a firewall accessible only through VPN. Visual Studio .Net and Crystal Reports 8 and 10 are installed on the server (read below why this is, I won’t explain here). This project has no project or solution file, as it was written in 2003 and the developer in-charge had a certain way of running projects for the web, which was not the most ideal. Needless to say, he’s no longer with the group. The ProblemWhen trying to run the application, I get the following nice 500 level error message from IIS: Server Error in '/' Application. Cannot find KeycodeV2.dll, or invalid keycode. Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code. Exception Details: CrystalDecisions.CrystalReports.Engine.InternalException: Cannot find KeycodeV2.dll, or invalid keycode. Fun. So, I spent about 4 hours yesterday and an hour this morning looking up what the possible answer could be. One of the first things I see on Google is people mentioning the addition of certain Merge Modules to the solution for the project. Such an example can be found on the vbCity/devCity.Net Forums. However, this solution doesn’t apply in my case because of the following reasons:
Please refrain from making comments regarding all of the atrocities listed above. I understand that this project is awry and should be scrapped, remade, yadda yadda. However, I have voiced these concerns to the appropriate individuals and we have to get approval from our customer before proceeding with said fix. So, what other possible solutions for this problem could exist, I wonder? More Googling yields a potentially worthwhile solution which requires access to the registry. That’s fine with me, as I’m used to working in the registry. This BusinessObjects Knowledgebase article stated that I need to modify the following 2 registry keys and give access to the user that ASP.NET is running as. The keys are:
When I gave the ASP.NET user read access to the files, I then reloaded the page and got the same error message. Reading the article further revealed that I had to register the keycodev2.dll file via regsvr32. Well, upon issuing the following command: Regsvr32 "C:\Program Files\Common Files\Crystal Decisions\1.0\bin\keycodev2.dll" I get the following error message: DllRegisterServer in C:\Program Files\Common Files\Crystal Decisions\1.0\bin\keycodev2.dll failed. Return code was: 0x8002801c The knowledgebase article then stated that I needed to look at another Knowledgebase Article which turned out to be total nonsense. So, back to Google. I then found this absolutely brilliant article that discussed a potential solution to the error listed above. However, this sent me jumping through hoops to try to look at the dependencies of the keycodev2.dll file and then try to monitor the registry entries that were being hit, only to reveal no such luck. So, I continued looking for another solution online and found yet another Knowledgebase article that discussed a fix when deploying a Crystal Reports application. This didn’t resolve or even come close to the overall issue, but I finally found a PDF article that was right up the alley of what I was trying to do, especially in terms of hosting the application. Unfortunately, it contained the same bit of information that the first knowledgebase article had in it. But, there was something in the article that made me realize what the problem was - access to the registry. Potential SolutionI had known this entire time that my user account had Administrative privileges. Unfortunately, Administrative privileges doesn’t always mean that everything is readable and writable by the Administrator. Sure enough, when I looked back at those registry keys listed above, neither had even read access for the Administrator. I quickly gave the Administrator account Full Control and made sure it permeated to all subkeys under each of those keys listed above. I reran the regsvr32 command listed above and v’oila! The DLL registered successfully! This was a problem I had while trying to send email from my local workstation through a web application. The script would execute fine, but I wouldn’t receive any email. Upon further investigation (which included walking through a debugging session to find out what was going wrong), I came across an exception when trying to use: SmtpMail.Send(email) The exception that was thrown have the following error message: **The message could not be sent to the SMTP server. The transport error code was 0x800ccc15. The server response was not available ** After a couple of minutes of realizing that I was not using localhost as my SMTP server, I figured there was either a problem with my mail relay, or something wrong with my workstation. A couple of Google hits returned that the problem was a VirusScanner issue. Sure enough, when I took a look at my Access Protection settings in McAfee VirusScan Enterprise 8.0i, one of the ports that was being blocked from sending traffic was port 25. There were 3 possibilities that I could have taken to resolve this:
All three of these solutions worked for about 5 minutes and allowed email to be sent through my application. However, after that 5 minute period, the rules were restored. I’m not entirely certain why they were restored despite my making sure that they were saved and took immediately after closing the VirusScan Console, but I’m in the process of figuring that problem out. It never ceases to amaze me how many outside dependencies there are for PHP. When trying to get a PHP application to connect to an LDAP server over SSL, you have to have the following:
Yes, but once you have all that done, then you need to hope and pray that it will connect successfully. On a Linux server, this is definitely a possibility (but a treacherous task at that). On a Windows machine: forget it. You might as well count your losses and start coding your application in .Net before you try connecting to an LDAP server via SSL with a Windows box (that or you need to be really good at compiling opensource software on Windows machines). The ErrorSo, here’s the error message I’m getting in my PHP app: Warning: ldap_bind(): Unable to bind to server: Can't contact LDAP server. Pretty generic error message right? It can be anything. I’m guessing, though, that it’s something with OpenLDAP. That’s why it comes with the wonderful tool `ldapsearch`. This _should_ help me figure out if it’s an application problem or a OpenLDAP problem. neraath:~/> ldapsearch -b ou=people,dc=example,dc=com -H ldaps://host.example.com searchMailbox=neraath ldap_sasl_interactive_bind_s: Can't contact LDAP server (-1) Once again, a pretty generic error message. If you try to Google that error message, you’re not gonna get anywhere. This is where OpenLDAP’s debugging switch turns out to be quite handy. My favorite: `-d 7`. Watch it in action: neraath:~/> ldapsearch -b ou=people,dc=example,dc=com -d 7 -H ldaps://host.example.com searchMailbox=neraath ldap_create ldap_url_parse_ext(ldaps://host.example.com) ldap_pvt_sasl_getmech ldap_search put_filter: "(objectclass=*)" put_filter: simple put_simple_filter: "objectclass=*" ldap_send_initial_request ldap_new_connection ldap_int_open_connection ldap_connect_to_host: TCP host.example.com:636 ldap_new_socket: 3 ldap_prepare_socket: 3 ldap_connect_to_host: Trying IP.ADDRESS.HIDDEN.HERE:636 ldap_connect_timeout: fd: 3 tm: -1 async: 0 ldap_ndelay_on: 3 ldap_is_sock_ready: 3 ldap_ndelay_off: 3 TLS: could not load client CA list (file:`',dir:`/etc/apache2/ssl.crt'). TLS: error:0906D06C:PEM routines:PEM_read_bio:no start line pem_lib.c:642 TLS: error:0906D06C:PEM routines:PEM_read_bio:no start line pem_lib.c:642 TLS: error:0200100D:system library:fopen:Permission denied bss_file.c:278 TLS: error:20074002:BIO routines:FILE_CTRL:system lib bss_file.c:280 ldap_perror ldap_sasl_interactive_bind_s: Can't contact LDAP server (-1) Lo-and-behold the answer becomes evident: TLS: could not load client CA list (file:`',dir:`/etc/apache2/ssl.crt'). I change the /etc/openldap/ldap.conf file line ‘TLS_CACERTDIR /etc/apache2/ssl.crt’ from what it is to ‘TLS_CACERTDIR /etc/ssl/certs’. I re-run the above command and it prompts me for a password. This is definitely a good sign. Running it again in my PHP code? Of course not. Step 2: Google Some MoreAfter more wonderful Googling for the most generic PHP error possible, I find that the problem may potentially be the certificate (view the thread). So, I decide to try to figure out how to actually view the certificate that’s on the server (in case it is self-signed or not trusted, somehow). This takes me the better part of half an hour, but I finally figure out the openssl command necessary to view the public key / certificate of a service: openssl s_client -connect host.example.com:ldaps This gave me the public key necessary to save and then place in at /etc/ssl/certs/host.example.com.pem. After doing so, I ran `c_rehash` and then modified my /etc/openldap/ldap.conf file. I added the following lines to the config: URI: ldap://host.example.com TLS_CACERT /etc/ssl/certs/host.example.com.pem After restarting Apache and testing the PHP file, things seem to be going a little smoother. No more connect errors. I will update if something goes awry, though. Well, it’s been a really long time since I last updated my blog and let everyone know what’s been going on in my life. In essence, I’ve been busy as usual, but have made progress by leaps and bounds in most things I’m actually involved in, and also have a new addition to our (Melissa and my) family (more to come later). So, a few weeks ago, Melissa and myself went to Denver, Colorado for a break from College Station and so that I could take some training in the infamous (and totally ripped off) programming language C# using the ASP.NET 2.0 framework. The reason I say it’s totally ripped off is that if you learn the language and learn Java (or vice-versa), you’ll notice that C# = Java. Barring that fact, I had a really cool instructor named Michael who kept me interested in learning the language and I did learn a lot. Essentially, I learned the syntax and how C# works and afterwards learned how to use Visual Studio 2005 along with parts of the Framework and how to create ASP.NET websites - simple ones at least. Besides the awesome (yet expensive learning) that it was, Melissa and I got to know her Aunt Kathy and Uncle Greg as well as do fun and cool things around Denver, a town that I haven’t been to in a long time. While we were in Denver and staying at Aunt Kathy’s place, I fell in love with their large Lab and Golden Retriever dogs. It reminded me of how much I had always wanted a big dog, but never had one. They were extremely sweet animals and I told Nissa that we had to get a dog sometime in the future. I was thinking she was going to get one for me for my birthday, but as it turned out we went out and got a Collie puppy (also something I had always wanted). We had quite a bit of troubles trying to adopt it (read Nissa’s article), but we were happy when we finally got to adopt her. She’s truly very sweet and utterly cute and Melissa made me extremely happy that she did that for me (really for us). The collie is what Melissa had expressed that she really wanted, and when we went to the pound to look for a puppy, she saw the collie (we named her Sophie, eventually), she fell in love with her and it really seemed as though I wasn’t going to get out of the pound without her. I’m not upset by any means, though. Collies are sweet, wonderful, and really smart dogs - not to mention it’s the official mascot of A&M, but that’s not a selling point for me. Past that, it’s been crazy-busy at work because I’ve been involved with so many projects that have stringent deadlines and high requirements (isn’t that how it usually goes?). All of the projects are PHP, none of my time is actually budgeted to them (with the exception of one), and all of them have SQL Injection vulnerabilities! As of now, I’m in Chicago taking the advanced C# course right at this moment. The course has been even better than the intro course that I took. Our instructor Brad is very outgoing, humorous, and very intelligent. The course has definitely helped me to learn a lot about C# and I’m really looking forward to building websites with it. Another really cool thing is my business partner Tom came up yesterday and is staying until Friday. I don’t get to hang out during the day, but the evenings we actually get to hang out. I feel really bad because I didn’t bring my wife along with me (because we didn’t have the money for it). From now on, though, I’ll definitely need to bring her along (assuming she can and assuming we can afford it). I love her dearly and I hate leaving her alone, and she likewise hates being left alone. In any case, back to my course. I’ll update soon (hopefully). For many of you who use Komodo, you will have undoubtedly come across the Source Code Control feature available within it. This feature works GREAT with MacOS X and Linux systems, but if you have ever tried to use it within Windows, it’s a bit tricky to get working properly (if you’ve even been able to do that). I’ve been tackling the issue for the past hour or so (after having tried it in the past - but to no avail), but now I think I’ve figured out what’s up with this damn thing. It revolves around using a combination of PuTTY, Subversion (NOT TortoiseSVN), and (of course) Komodo. Before we get started, you might want to check out this forum thread as this is what gave me some hints as to what to do, though I had to take it all with a grain of salt since it was so messy. If you don’t care, then read onward! These first steps are really quite quick, and I don’t care to explain how to do them (as I expect you to figure out how to install applications yourself). If all else fails, RTFM.
Enjoy. Well now, here’s an interesting problem I had with Perl on the new Mac Xserve running Intel Xeon 64-bit processors. One of our customer’s had a CGI website (cringes) and was using DBD::MySQL to access the MySQL database. Upon initial observations, permissions had been setup incorrectly and the httpd.conf file was not setup properly for CGI executables. Past this, I find that the server has dependency problems. This was found due to the following error message in the /var/log/httpd/error_log file. The particular error was: [Mon May 7 15:43:45 2007] [error] [client xx.xx.xx.xx] Premature end of script headers: /Library/WebServer/CGI-Executables/webevent.cgi install_driver(mysql) failed: Can't locate DBD/mysql.pm in @INC (@INC contains: /Library/WebServer/webevent/lib /System/Library/Perl/5.8.6/darwin-t hread-multi-2level /System/Library/Perl/5.8.6 /Library/Perl/5.8.6/darwin-thread-multi-2level /Library/Perl/5.8.6 /Library/Perl /Network/Library/Per l/5.8.6/darwin-thread-multi-2level /Network/Library/Perl/5.8.6 /Network/Library/Perl /System/Library/Perl/Extras/5.8.6/darwin-thread-multi-2level / System/Library/Perl/Extras/5.8.6 /Library/Perl/5.8.1 .) at (eval 8) line 3. Perhaps the DBD::mysql perl module hasn't been fully installed, or perhaps the capitalisation of 'mysql' isn't right. Available drivers: DBM, ExampleP, File, Gofer, Proxy, Sponge. at /Library/WebServer/webevent/lib/db/dbconnect.pm line 58 So, I proceed to install Perl modules. But wait, CPAN’s bitching about an upgrade to CPAN being available. Fine, let’s give it what it wants: CPAN> install Bundle::CPAN -- CPAN INSTALLS UPDATE -- Cool, now time to move to installing DBI: CPAN> install DBI -- INSTALL SUCCESSFUL -- Now for the last bit, DBD::mysql: CPAN> install DBD::MySQL <snip> t/utf8...............install_driver(mysql) failed: Can't find 'boot_DBD__mysql' symbol in /Library/Perl/DBD-mysql-4.001/blib/arch/auto/DBD/mysql/mysql.bundle at (eval 3) line 3 Compilation failed in require at (eval 3) line 3. 2 tests skipped. Failed 25/28 test scripts. 413/418 subtests failed. Files=28, Tests=418, 2 wallclock secs ( 1.54 cusr + 0.35 csys = 1.89 CPU) Failed 25/28 test programs. 413/418 subtests failed. make: *** [test_dynamic] Error 255 </snip> Damn, talk about something unexpected. After reading a few emails, forums, and getting down right frustrated with everything, I find this email note. This isn’t completely correct, in that it turns out you don’t have to install another copy of MySQL in some temporary location for the libraries - you have everything you need, assuming you’ve already installed XCode Tools. So, what DO you have to do? The following: shell> cd /path/to/.cpan/build/DBD-mysql-4.001/ shell> perl Makefile.PL --testuser test --testpassword test --testsocket /var/mysql/mysql.sock --cflags="-I/usr/include/mysql" --libs="-L/usr/lib/mysql -lmysqlclient -lz -lm" shell> make shell> make test (should work now) shell> make install Understanding of why Perl was so brokenWell, it wasn’t exactly Perl’s fault. It’s MySQL that comes on Apple’s Xserve. Apple, you question with an unquestionable doubt in your mind? Yes, Apple. Check this out: shell> mysql_config --libs -arch ppc64 -arch x86_64 -pipe -L/usr/lib/mysql -lmysqlclient -lz -lm shell> mysql_config --cflags -I/usr/include/mysql -fno-omit-frame-pointer -arch ppc64 -arch x86_64 -pipe Now isn’t that funny! On my new Xeon Xserve, the architecture specifications (which for some odd reason appear in BOTH the cflags AND libs flags which normally appear ONLY in the cflags) are for BOTH ppc64 AND x86_64… AFAIK, this server is Intel 64-bit based, not PowerPC any longer. So, when Perl goes through and autoconfigures its switches, these architecture flags cause the tests to blow up because it’s expecting a completely different set of tools that are expected to work on the PowerPC architecture. Anywho, it’s working now, and that make me (and my client) happy. I’m here in Austin, TX today at the SANS: Web Application Security Workshop (I was also here yesterday, too). I hope to be able to provide an accurate review for this nearly worthless workshop that many of us from CIS Customer Applications are attending. There are a couple of individuals who believe that the information being taught here is somewhat worthwhile, but most of us from the group either know everything that’s been taught so far, or find some of the information being taught doesn’t relate to us. For a quick synopsis, here’s what I would have to say: If you are a intermediate or experienced developer, you will be absolutely bored with this workshop. If you are an executive who has not much technical know-how, but want to learn about security for your web applications, this is a worthwhile program for you to attend. Be aware, however, because there are some things that executives don’t need to (or don’t care to) learn about in this. Regardless, this is the most watered down version of a so-called technical workshop I’ve ever been through. Read on to find out how ridiculous some of the things we learned were. Howdy everyone! I’ve finally finished the move of my blog to the new server, and everything (including my photographs) have been restored! Please browse around and don’t hesitate to email me at chris at chrisweldon dot net should you notice anything that’s broken. |