the truth about hacked software

I want to get something out in the open.  It’s not illegal to hack your software.

This is probably contrary to what you might assume when you hear the words “hack” and “software” used in the same sentence, but there is an important distinction to make: hacked software is not the same thing as pirated software.

Let’s throw out a couple examples.

The OSx86 Project

OSx86 is a project whose goal is to allow people to install the Apple OSX operating system on Intel-based PCs.  (Actually, allow isn’t quite the right word…you can already do it, it’s just not made very easy – the OSx86 project is to provide tools (and documentation) to make it easy (or easier, anyway)).  The theory here is that now that Apple is using Intel chips to power their computers as opposed to Motorola chips, the hardware infrastructure isn’t a completely different animal the way it used to be.  PCs and Macs are much more closely related.  This is amplified by the fact that OSX is a BSD-based system, which is a Unix variant that shares a lot of similarities with current popular Linux distributions like Ubuntu, particularly with the ‘sudo’ element (a commandline argument that allows a user to take on the roles of the system administrator without the need to log in as the root user/sysadmin – much like the User Access Controls that exist in Windows Vista and 7).  It is a violation of Apple’s terms of use to install OSX on a PC.  However, this is not a violation of the law.  (They might like you to think it was, but just last year Apple was overruled in a case against the ‘jailbreaking’ of iPhones while they were under contract with AT&T.  Installing OSX on a PC is similar to said jailbreaking, just applied to an actual computer.)

Ripped Music

You may not think that ripping music from a CD counts as software, but the theory holds and mp3s are nothing if not digital files to be manipulated by another software application.  You may also assume that ripping a CD to create mp3s is not violating any terms of anything.  The RIAA, however, would have you believe that you are violating copyright law by ripping mp3s from a CD that you own.  The reason here being that the record company may also sell those mp3s themselves and just because you can create your own mp3 copies doesn’t necessarily mean you should.  On the other hand, we’ve all come to accept the common terms of property law which states that, once you purchase something, you can do pretty much whatever you want with it.  (This is why it’s no more illegal to copy a record onto a blank cassette than it is to sell the record to a used vinyl shop for cash.)  In this, the recording industry really has no bite since we’ve already established that copying music to a tape doesn’t violate any law (although they tried to disallow that in the 80s), so there’s no reason why creating a digital copy should be any different (they would disagree again, pointing out that it is possible to create digital copies of music with today’s technology that are a direct facsimile of the original – to which we all say “…so?”). 

Windows Genuine Advantage Validation Hacks

This is what lead me to start writing this post in the first place.  When Windows 7 was in beta, I signed up and was using Windows 7 for almost a year in it’s early beta and release candidate forms.  I was so impressed that I decided to actually purchase a copy for each of our computers.  Of course, according to Microsoft, Windows 7 beta/RC was not for use on any machine you actually use (which sort of defeats the purpose IMO) and there was no direct upgrade path to a retail version of Windows 7 from the RC.  It wasn’t long before someone found a way around this, which even worked for me, who bought Windows 7 Home Upgrade (the RC had the featureset of Windows 7 Ultimate).  But fast forward to both hard drives on both my computers failing (at different points).  Though you are allowed to do a format and install with an upgrade version of Windows 7, the license key is not valid for a full install,  I had to find a way to workaround the Windows Genuine Advantage Validation to use the copy of Windows that I purchased.

Commercially-Supported GPL Software

This one is close to home because not only do I write commercially-supported GPL software (in the form of Museum Themes), but I also support commercially-supported GPL software (in the form of Event Espresso). In this instance, hacking may not be anything more malicious than taking the code and modifying it for your own purposes (something that is allowed by the software license). But what if the means by which you obtained the software wasn’t one of the “official” channels? By the terms of the GPL, anyone, anywhere, for any reason has the right to take GPL software and distribute it in kind as long as they do not alter the GPL license itself. This means that you could take GPL software that you purchased and post it on your website for people to download.

However, with most commercially-supported GPL software, what you are actually paying for is not the software itself, but rather the support (and the knowledge that the software is being maintained, tested, and the developers will presumably fix any bugs you may find – all things that may be harder to come by when you are working with free – as in beer – GPL software). If you took the example above and posted your commercially-supported GPL software on your site, you would likely earn the ire of the developers if not violate the terms you agreed to when you purchased the software, and they would more-than-likely deem you invalid for receiving any further support or updates.

Common threads

At this point you should be seeing a pattern.  “Hacked” software is making the software do something that wasn’t the intended use by the manufacturer.  The consequence isn’t death, the FBI won’t come after you over your illicit VHS copies of movies you rented from Blockbuster, and you won’t go to jail.  You will not, however, be able to get support for whatever software it is that you are hacking.  The EULAs that you click through without reading, though they sound like legalese, are at the end of the day just license agreements and generally not a basis for legal action.  We have become so used to clicking through EULAs without reading that, as a result, we only follow the terms of them as far as it resembles common sense or, at the very least, supports what we were already intending to do with it.

Breaking the rules

I was going to end this post here, but I’ve recently been made aware of something that is making the rounds in the Warrior Forum.  For those of you who don’t know, the Warrior Forum is basically where spammers and black hat internet marketers are made.  It is to scammy online money-making schemes what 4chan is to griefing.  Recently, some brilliant member of the forums realized that because the terms of the GPL allow you to redistribute the software (even repackage and resell the software) that you could potentially make a lot of money stealing other people’s code and selling it.

Here’s the problem with that.

GPL software is released without any warrantee that the software even works.  No guarantee is made for support of any kind.  As discussed previously, that’s what you’re paying for.  How likely is it that the guy you got a free copy of a WooTheme from is going to help you out when you have a problem with the theme or want to upgrade it to the latest version?  Not at all.  Go to WooThemes for support?  Sorry, if we don’t have a record for your purchase, you’re SOL.  This hurts not only the customer trying to use the theme but, ultimately, becomes a big headache for the guy trying to redistribute it because he probably didn’t realize that he’s going to have to help (or ignore) the people he gave his theme to.  For someone out to make a quick buck, this was probably not part of the plan (however, for anyone actually in the business of selling GPL-licensed commercial software, this is precisely the plan).

The moral

Hacking software or using hacked software is not illegal.  Once it’s (legally) in your possession, you ultimately have the right to do whatever you want with it.  However, doing so means you should at least be aware of the consequences, namely: you’re on your own.  If you break anything after hacking your software (or using someone’s patched version of commercial software), you can’t go back to the developer and ask for a refund, or support, or much of anything, really.  Hacking is not piracy and shouldn’t really even imply piracy (though pirated software often requires a hack in order to bypass the built-in protection against just that).  Hacking is just code, which, broken down are just words, which are protected by article one in the constitution allowing free speech.  That said, there are many cases when the forces in place guiding you toward actually purchasing or using the software legitimately have benefits that outweigh whatever benefits of the hacked version.  Maybe this is in the form of support from the developer or maybe you just believe in the product and want to help them keep writing good code.  As a free-thinking individual, it is up to you to make the choice for yourself and understand the consequences of either decision.

WP_Query pagination problems? Here’s a hack

It happens every time I use WP_Query. I get a beautiful-looking custom WP_Query. Then I try to add pagination and everything goes to hell.

I’ve spent hours looking up solutions. Every time. Nine times out of ten, they don’t work. And for no discernible reason. Here’s a hack that worked for me, and is mostly for my own benefit so I don’t forget it next time I am in this situation, but maybe it will help you.

This hack requires Lester Chan‘s plugin WP-PageNavi. Go get it and come back.
For me, this applies specifically to using custom post types. If I wasn’t using CPTs, my WP_Query might not have any problems. Feel free to let me know in the comments if you spot an issue with the way I’m doing things. As I said, this is a hack — meaning it’s not the preferred way to do this — but it’s a functional hack at least.

Let’s start with the query:

			rewind_posts();
			global $wp_query, $paged;
			$temp = $wp_query;
			$wp_query = null;
			$wp_query = new WP_Query();

This is pretty basic. I’m running a rewind_posts() here because I have some custom queries going on in the sidebars, so I threw this in there just to be on the safe side. The next bit is where the hack starts coming in…

			$showposts = 12;
			$offset = ( ( $showposts * $page ) - $showposts );

Here we introduce two variables, both of which we will use in the arguments later. $showposts is a hard-coded rule for the posts_per_page argument. Yes, this is required. The reason will become evident by looking at the next line. Our $offset is being multiplied by the $showposts value (for me, this is 12) and then subtracted by that value again. This is how we are going to fix the issue of not being able to go into paged navigation because it only displays the first page worth of posts — by creating an offset that is multiplied by the current page you are looking at ($page is a global variable that is built into WordPress to display the current page).

Now the $args:

			$args = array(
				'post_type' => 'ap_products',
				'posts_per_page' => $showposts,
				'offset' => $offset,
			);
			query_posts($args);

This is pretty straightforward also. All we’re doing here is declaring the post type (which is just for my use, you can omit this if you aren’t using a custom post type, or replace with your own post type), and then feeding the $showposts and $offset values in here. Then we’re running our query. The full loop looks like this:

<?php the_post(); ?>
	<div <?php post_class(); ?> id="post-<?php the_ID(); ?>">	
	<?php 			
			rewind_posts();
			global $wp_query, $paged;
			$temp = $wp_query;
			$wp_query = null;
			$wp_query = new WP_Query();
			$showposts = 12;
			$offset = ( ( $showposts * $page ) - $showposts ); 
			$args = array(
				'post_type' => 'ap_products',
				'posts_per_page' => $showposts,
				'offset' => $offset,
			);
			query_posts($args); 	?>				
			<div class="entry">
				<?php while ( have_posts() ) : the_post(); ?>				
					<!-- do stuff -->
				<?php endwhile; ?>
				<?php if(function_exists('wp_pagenavi')) { echo '<div class="navigation"><span class="pre-navi"><a href="' . home_url() . '" />1</a></span>'; wp_pagenavi() . '</div>'; } ?>
				<?php $wp_query = null; $wp_query = $temp; ?>
			</div>
		</div>

Notice what I’m doing at the end with the wp_pagenavi function. I’ve added this into my style.css:

.current { display: none; }
.pre-navi { float: left; }

This makes it so that the current page doesn’t display at all. I’m doing this because the current page is always 1 with my fantabulous error, and this way I can replace the page 1 with one that actually links (if you’re on any page other than 1).

And that’s it. It’s not elegant, but it works, and the only real issue is that page 1 is always a link. If you like this solution (or if you hate it), let us know in the comments!

Multiple loops, post formats, and content types in a single home page template

Wow. That title is a mouthful. And given the improbable combination of different content types, I’m actually somewhat surprised that I did, in fact, pull off just that. In working on a client site for a Christian ministry in the Democratic Republic of Ghana, I set out today to create this:

ibm homepage Multiple loops, post formats, and content types in a single home page template

What we have here is a Dynamic Content Gallery at the top, a YouTube video, some static content, and then two different areas for recent posts in different formats. The key here is that everything should be dynamic. We’re not looking to slap a YouTube embed in a home page template; I want to be able to use the new WordPress Post Formats to send the most recent video post to that slot whilst juggling all sorts of other dynamic content from everywhere else and — if at all possible — avoid duplicating anything. Here’s to proving it’s not impossible.

So, the first step is to take care of the DCG. This is the easy part.

12
13
14
15
16
17
	/* first, if we have dcg installed, display dcg inside it's own div */ 
if (function_exists ('dynamic_content_gallery')){ ?>
	<div id="dcg">
		<?php dynamic_content_gallery(); ?>	
	</div>
<?php } ?>

I’ve actually got featured images set up on my other pages in this theme, so if you wanted to do an else for the case where DCG didn’t exist, you could do something like this:

	/* first, if we have dcg installed, display dcg inside it's own div */ 
if (function_exists ('dynamic_content_gallery')){ ?>
	<div id="dcg">
		<?php dynamic_content_gallery(); ?>	
	</div>
<?php } else {	
// if you don't have dynamic content gallery, maybe a featured image would work?
// this is borrowing the code pretty much straight from Twentyten, so you'll need to add this to your functions.php, too
// so check with Twentyten and get that sorted first
	if ( is_singular() && current_theme_supports( 'post-thumbnails' ) &&
			has_post_thumbnail( $post->ID ) &&
			( /* $src, $width, $height */ $image = wp_get_attachment_image_src( get_post_thumbnail_id( $post->ID ), 'post-thumbnail' ) ) &&
			$image[1] >= HEADER_IMAGE_WIDTH ) :
		// Houston, we have a new header image!
		echo get_the_post_thumbnail( $post->ID );
	elseif ( get_header_image() ) : ?>
		<img src="<?php header_image(); ?>" width="<?php echo HEADER_IMAGE_WIDTH; ?>" height="<?php echo HEADER_IMAGE_HEIGHT; ?>" alt="" />
<?php } ?>

(Note: this part isn’t tested, per se…I’m just combining two different things I have going on in this theme. It should work, but if if borks your theme let me know, and I’ll fix my code.)

Okay, back to my code.

After DCG, I’ve got a video and static content. The static content is going to be whatever they have on their Home page. The video is the most recent video post. We’re using Post Formats so — like the featured image snippet above — you’ll need to enable that in your functions.php to get that working before you try this.

19
20
21
22
23
24
25
26
<div class="content home">
<?php /* this is the main home page stuff...there's a lot going on here 
	     first of all, we're displaying the most recent VIDEO post */ 
	query_posts( 'showposts=1' );
		if (have_posts()) : while (have_posts()) : the_post(); 
			if (has_post_format( 'video' )) { ?>	
				<div <?php post_class(); ?> id="post-<?php the_ID(); ?>"><?php the_content(); ?></div>
        <?php } endwhile; endif; rewind_posts();

So far, so good, and nothing too complex yet, right? All we’re doing here is running a loop that’s limited to 1 post, and making sure that post is a video post. Here’s where it gets fun.

27
28
29
30
31
32
33
34
35
		/* next, we're displaying the regular home page content.  That's right, you heard me, we're adding page content in between a bunch of dynamic post stuff */
		$ibm_home_page = new WP_Query('post_type=page&name=home'); 
		while ($ibm_home_page->have_posts()) : $ibm_home_page->the_post(); ?>
			<div <?php post_class('home-content'); ?>>
				<?php the_content(); ?>
			</div>
		<?php endwhile; rewind_posts(); ?>
	<div class="clear"></div>
	<hr />

I’ve completely switched over to WP_Query to be able to grab a Page with the slug ‘home’. But since I did rewind_posts, the Loop isn’t completely freaking out. Underneath this, we’ve got even more fun times.

36
37
38
39
40
41
42
43
	<?php /* down here, we're doing two more things.  First order of business is to display the next post making sure that the next post ISN'T the video post above. we're also excluding sticky posts here to get a more linear order going on. */ 
	query_posts( 'caller_get_posts=1&showposts=1' );
		if (have_posts()) : while (have_posts()) : the_post(); if (has_post_format( 'video' )) { query_posts('offset=1&caller_get_posts=1&showposts=1'); } else { ?>
			<div <?php post_class('home-excerpt'); ?> id="post-<?php the_ID(); ?>">
				<a href="<?php the_permalink() ?>" rel="bookmark" title="Permanent Link to <?php the_title_attribute(); ?>"><h2 class="the_title"><?php the_title(); ?></h2></a>
				<?php the_excerpt(); ?>
			</div>
		<?php } endwhile; endif; rewind_posts(); ?>

Woah there. It was at this point that I started running into a couple snags. First of all, I kept getting any sticky posts popping up at the top of the list, above my single post I was trying to display. This is only supposed to be a single post excerpt, so that was not going to work. Second, the next post, under my sticky post, just happened to be my video post which I created to test the video Post Format. Which is ridiculous, right? You don’t want your video and then a big empty space under your video (because I’m using the_excerpt rather than the_content) with the title of the post for…your video. And that would be bound to happen anytime you posted a video. Ninja coding skills needed to be summoned. Or, barring that, ninja Googling skills…

The first half of the query is straightforward. caller_get_posts gets the next posts in the loop sans sticky posts. Golden. And we only want one, so that part’s obvious. Next, after we do our normal loop stuff, I throw in this if (has_post_format( 'video' )) stuff that looks like it does pretty much the same thing. Well…it does. With one exception: if the next post is a video post, we’re going to offset the query by one and grab the one after that, effectively skipping your video. It’s ugly but it works, and that’s all I wanted.

This last bit is just recent updates. With all the querying and offsetting, I know we’re going to have some issues here. But I don’t care too much about this section because all I’m looking to do here is display some links from some recent posts. On another site, I might do random posts or popular posts or most commented posts here, and none of the stuff we’ve done up to now would even matter for these. Instead, what I’m doing is adding an extra offset, and if I skip a post, no big deal — chances are, that post will be featured in the DCG above, anyway.

44
45
46
47
48
49
50
51
52
53
	<div class="home-updates">
		<h2>Recent Updates</h2>
		<?php /* finally, this last section is just a recent posts area.  we care a bit less here about sticky posts or video posts, so really the only thing I'm concerned about is the offset, which i've incremented by 1 extra just in case.  this may result in some duplicates, or, alternately, some posts missing, but, again, they're just links and they're not taking up much real estate and I'm not too concerned about it */
		query_posts( 'showposts=5&offset=2' );		
			if (have_posts()) : while (have_posts()) : the_post(); ?>			
				<a href="<?php the_permalink() ?>" rel="bookmark" title="Permanent Link to <?php the_title_attribute(); ?>"><strong><?php the_title(); ?></strong></a><br />
			<?php endwhile; endif; rewind_posts(); ?>
	</div>
</div>    
<div class="clear"></div>

And there you have it. The real star of the show here is rewind_posts. If you’ve ever done multiple loops before rewind_posts came along, you’ll know that all sorts of wacky stuff can come up that throws your loop(s) off. rewind_posts allows you to use multiple loops in the same template, and then go on and do some more loops somewhere else, and nothing goes horribly awry.

Hopefully this gives someone out there some ideas of what you can do with multiple loops using query_posts. There isn’t a lot of stuff out there yet on Post Formats — particularly excluding post formats, so that was one area I sort of had to wing it. If anyone has some awesome ideas, I’d love to hear them.

(By the way, all the example text used in the mockup above comes courtesy of F*** Lorem Ipsum, which I’ve been using as an alternative to the Lorem Ipsum Generator I’ve used for years. F*** Lorem Ipsum pulls text from TV shows and commercials and is able to throw in links and line and paragraph breaks, too.)

web site security

can we really be that surprised by a hosting company that uses sex to sell its services?

i was listening to the replay of the teleconference hosted by WPSecurityLock (with special guests from GoDaddy) in light of the recent wave of website hacks that affected hundreds of sites not once, but twice.  it was actually when they were talking to a customer (one who had been hit twice) that a concern was raised in my mind.  the exchange went something like this:

a GoDaddy representative was on the line talking about ways to protect your site against attack, emphasizing the importance of keeping your software (be it WordPress, Joomla!, or whatever) updated.  — note: for the record, this seems like a lame cop-out.  yes, it’s great to keep your software updated, but when the attack is indiscriminately affecting php files — whether they belong to a known open source software or are completely custom-coded — i don’t see how this has any relevance on the situation at hand.  it should be noted that neither GoDaddy nor WPSecurityLock have been able to identify how intruders were able to access users’ sites and change the file permissions which allowed them to inject malicious code into the php files.  software version doesn’t really have any bearing whatsoever on that. —

after he said his piece, Regina from WPSecurityLock spoke with a customer who suffered in the first wave of attacks — actually the first client that they (WPSecurityLock) fixed, and then fixed again when the second wave hit.  she started talking about how, after the second intrusion, she noticed that all the files were left completely open in terms of file permissions (i.e. 777) and that she didn’t think he would have installed it that way.  he expressed gratitude for having them on his team because he admitted that he had absolutely no idea what she was talking about.

and that’s the problem isn’t it?

GoDaddy and other web hosts are saying you are responsible for your files.  you should know what goes into a WordPress installation so you can identify anything weird that’s not part of it.  you are expected to be familiar with FTP and changing file permissions.  but i think that most people hear “file permissions” and it’s like you’re suddenly speaking like the teachers in Charlie Brown: wah wah, wah-wah wah-wah wah.

godaddy: drunk on the job or just intoxicated by mon--er, success?you need to speak to the lowest common denominator here.  if you’re going to provide 1-click installations for any software at all, you have to make sure that when your auto-installer does its’ job it’s not leaving customers open to attack.  because no one that’s going to use a 1-click installer is going to know anything about FTP or chmod, that’s why they used the installer.  and even some people clever enough to know their way around FTP and WordPress’ patented 5-minute install might not know the proper file permissions for their site and just use 777 because it works.  we are lazy.  we use the same single password for everything we do online.  we can’t be expected by our service providers to be educated on proper security practices and safety procedures.  that’s what the geeks with the smelly t-shirts and glasses that make them look bug-eyed are for (although i wrote about some ways to help make your website more secure on arcane palette on tuesday).  no, it shouldn’t be the webhost’s responsibility to wipe their customers’ butt for them when it comes to securing their site, but neither do i think it’s fair that hosts honestly expect otherwise.  especially if one infected site on a server can spread to any or all the other sites hosted on the same shared server which seems like it was the case for both GoDaddy and Network Solutions.

wait, websites?  i just came for the pornit would be great if everyone remembered to change permissions on their files after installing software like WordPress.  it would be great if everyone knew and used the special extra security tricks WPSecurityLock mentions on the call, on their blog and in their free e-book.  but, i’m looking at you guys here, webhosts: the files may belong to your customers but they’re on your servers.  they, apparently, affect all the other sites on your servers (or have the potential to, anyway).  and you can point the finger everywhere except yourself as much as you like — you can say it’s the customer’s responsibility to keep proper permissions, you can say that old software has known exploits that can be used by hackers and that upgrading your software can even leave artifacts behind from older versions (so that, even if you are upgrading your software, you still aren’t safe) — but none of those things are going to make you any friends.  none of those things are going to make you into the good guy.  you know what is going to make you the good guy?  thinking for your customers.  taking care of the situation before it becomes a situation.  taking the role of assigning and/or correcting the file and directory permissions on a website out of the customer’s hands and taking responsibility for that yourself.  surely, by now, webhosts, you’ve figured out that people aren’t going to do something just because they’re told to do it.  surely you don’t really expect people to walk away from these widespread hacks and say “gee, i guess i should be more careful next time.”  unless that’s really part of the plan: give the user the responsibility, then when the shit hits the fan you can say “well, it wasn’t really our fault, but we can have one of our security analysts fix it for you for $150.”

wait.  nevermind.  i see the business model now.

i wish i could say that i made these pictures up, but this is actually how godaddy markets themselves