VOLUME IV - ISSUE www.phparch.com FEBRUARY 2005 Plus: Security Corner, Reviews, News and much more LEARNING PHP WAS NEVER THIS MUCH FUN php|Tropics Moon Palace Resort, Cancun, Mexico May 11-15 2005 Come learn PHP in Paradise with us (and spend less than many other conferences) Ilia Alshanetsky - Accelerating PHP Applications, Marcus Boerger - Implementing PHP OOP Extensions, John Coggeshall - Programming Smarty, Wez Furlong - PDO: PHP Data Objects, Daniel Kushner - Introduction to OOP in PHP 5, Derick Rethans - Playing Safe: PHP and Encryption, George Schlossnagle - Web Services in PHP 5, Dan Scott - DB2 Universal Database, Chris Shiflett - PHP Security: Coding for Safety, Lukas Smith - How About Some PEAR For You?, Jason Sweat - Test-driven Development with PHP, Andrei Zmievski PHP-GTK2 For more information and to sign up: http://www.phparch.com/tropics Early-bird discount in effect for a limited time! At php|tropics, take the exam and The Magazine For PHP Professionals Get Zend Certified and we'll pay your fees! TABLE OF CONTENTS php|architect TM Departments Features Editorial I N D E X Blogging and the Damage Done 10 by Christian Wenz What’s New! 49 PHP Under Fire Test Pattern 20 HTML_QuickForm and Smarty by David Perrin The Myth of Reusable by Marcus Baker 29 55 Review by Alex Pagnoni The ZEND PHP Certification Experience by Peter B MacIntyre Enterprise Development with the iConnect Architecture 40 The PRADO Framework by Qiang Xue 68 Security Corner PHP Security Consortium by Chris Shiflett 58 Secure Communications with PHP and SSH by Sara Golemon 72 exit(0); Welcoming PHP to the World by Marco Tabini February 2005 ● PHP Architect ● www.phparch.com EDITORIAL Blogging and the R A N T S TM Volume IV - Issue February, 2005 Damage Done E D I T O R I A L php|architect H ow can you tell if a technology has reached critical mass? Easy: you look at how much damage it’s causing Pretty much every human invention is neutral in itself; any benefits (or drawbacks) come from the way it’s used: atomic energy can be used to power a city or destroy it; cars make it travel over distances that were unthinkable just a hundred years ago possible, and are happily destroying our planet with their polluting emissions Blogs have finally reached the “do and die” level of usage They started as glorified online diaries Comments mutated them into electronic sounding boards RSS turned them into a self-publishing tool The corporate world has rapidly misused them into propaganda weapons Running your own blog, as many of our readers and authors do, is, in many cases, a liberating experience Personally, I like the idea of throwing my ideas out there in a free-form format and let other people take them apart, comment on them and, possibly, even use them Many people, it seems to me, have pretty much the same attitude with regards to how they run their blogs Where they go wrong, in my opinion, is in the fact that they continue to think of blogs as personal diaries, which is often incompatible with the way their readers see them For my part, as much as I love writing on my blog, I often find myself being overly cautious about what I write in it—because, no matter what I think, people see it not as “Marco’s blog,” but as “php|architect’s blog.” This severely limits, in my mind, the range of topics I can cover and how I can cover them In fact, this problem has come up more than once when people have criticized me either for dissing our competition or for failing to disclose ties with companies that were mentioned in my posts one way or another In both the instances I recall, the comments were misplaced—I didn’t dis the competitors, but simply expressed a personal preference, and the ties between us and another company had nothing to with my posts Still, I respect the fact that, to many people, my blog is a way to peek into the less-public face of php|architect, which is just fine but requires a bit more thoughts than “I’ll write about what I had for breakfast.” Some people—and many companies—have yet to figure out what the limits of blogging are Thus, we see employees of corporations posting proprietary information and getting fired for it (and justly so), and employees posting completely harmless information and getting fired for it anyway (in a decidedly unfair manner) What I find really funny is the fact that so much fuss is being made about blogs when they are, in fact, nothing more than the tip of the iceberg Clearly, the problem is somehow connected to the fact that a weblog reads like a friendly chat but Publisher Marco Tabini Editorial Team Arbi Arzoumani Peter MacIntyre Eddie Peloke Graphics & Layout Arbi Arzoumani Managing Editor Emanuela Corso News Editor Leslie Hill news@phparch.com Authors Marcus Baker, Sara Golemon, Peter MacIntyre, Chris Shiflett, Alex Pagnoni, David Perrin, Christian Wenz, Qiang Xue php|architect (ISSN 1709-7169) is published twelve times a year by Marco Tabini & Associates, Inc., P.O Box 54526, 1771 Avenue Road, Toronto, ON M5M 4N5, Canada Although all possible care has been placed in assuring the accuracy of the contents of this magazine, including all associated source code, listings and figures, the publisher assumes no responsibilities with regards of use of the information contained herein or in all associated material Contact Information: info@phparch.com General mailbox: Editorial: editors@phparch.com Subscriptions: subs@phparch.com Sales & advertising: sales@phparch.com Technical support: support@phparch.com Copyright © 2003-2004 Marco Tabini & Associates, Inc — All Rights Reserved Continued on Page February 2005 ● PHP Architect ● www.phparch.com NEW STUFF What’s New! N E W S T U F F php|architect launches php|tropics 2005 Ever wonder what it's like to learn PHP in paradise? Well, this year we've decided to give you a chance to find out! We're proud to announce php|tropics 2005, a new conference that will take place between May 11-15 at the Moon Palace Resort in Cancun, Mexico The Moon Palace is an allinclusive (yes, we said all inclusive!) resort with over 100 acres of ground and 3,000 ft of private beach, as well as excellent state-of-the-art meeting facilities As always, we've planned an in-depth set of tracks for you, combined with a generous amount of downtime for your enjoyment (and your family's, if you can take them along with you) We even have a very special early-bird fee in effect for a limited time only For more information, go to http://www.phparch.com/tropics Maguma Workbench 2.2 Maguma has announced the release of Maguma Workbench 2.2 On 20 January 2005, Maguma published the newest version of Maguma Workbench Maguma Workbench 2.2 has new features, more stability and a new pricing concept During the same period Maguma will also publish the Maguma Workbench SDK, for more independence to create new modules for your Workbench For this reason Maguma has created a competition for developers, to create new plugins The new features, like the PHP Function list, drag´n´drop and the hotkey F12 (hide/restore tool windows) brings you more efficiency Patches have also been applied to the PHP Code Parser, Class Wizard, Script Parameter Implementation and more (see Changelog for more details at http://support.maguma.com/?article=changelog220 ) With this release of Workbench we are also making a reality of “Make it your Workbench” which means now the core price of Workbench is only 69 Euro and it’s up to the user to choose which modules/features they want to add to the core product The core provides the basic features such as Syntax highlighting, Class browsing, and script execution, while the extra modules provide the added features such as local filesystem browsing, debugging, regular expression developer, and much more So each customer can buy only the function and modules that they need and will use For more information visit: http://www.maguma.com/ The Zend PHP Certification Practice Test Book is now available! We're happy to announce that, after many months of hard work, the Zend PHP Certification Practice Test Book, written by John Coggeshall and Marco Tabini, is now available for sale from our website and most book sellers worldwide! The book provides 200 questions designed as a learning and practice tool for the Zend PHP Certification exam Each question has been written and edited by four members of the Zend Education Board the very same group who prepared the exam The questions, which cover every topic in the exam, come with a detailed answer that explains not only the correct choice, but also the question's intention, pitfalls and the best strategy for tackling similar topics during the exam For more information, visit http://www.phparch.com/cert/mock_testing.php February 2005 ● PHP Architect ● www.phparch.com NEW STUFF PostgreSQL 8.0 The folks at PostgreSQL have announced the release of PostgreSQL 8.0 This is the first PostgreSQL release to natively run on Microsoft Windows as a server It can run as a Windows service This release supports NT-based Windows releases like Win2000, XP, Win2003 Older releases like Windows 95, 98, and ME are not supported because these operating systems not have the infrastructure to support PostgreSQL A separate installer project has been created to ease installation on Windows: http://pgfoundry.org/projects/pginstaller For more information visit: http://www.postgresql.org Netdoc 1.25 The people at visiomode.com have announced the release of Netdoc 1.25 Netdoc is a content management system that focuses tightly on content creation and editing Netdoc 1.25 comes with a complete user privilege system Websites can be made global readable, only readable to some, or even global writable These privileges can be applied also to any part of the website, and defining them takes generally only a couple of rules Netdoc is made with PHP and it stores the data into a MySQL database and uses Apache as a web server Netdoc is installed on the server and it creates dynamic pages with friendly URLs The site is updated through the web interface directly on that same server and thus there is no pushing of content or FTP transfer taking place at any time For more information visit: http://www.visiomode.com curl and libcurl 7.13.0 curl.haxx.se has announced the latest release of curl and libcurl 7.13.0 Some of the changes include: • • • • added —ftp-account and CURLOPT_FTP_ACCOUNT added CURLOPT_SOURCE_URL and CURLOPT_SOURCE_QUOTE obsoleted CURLOPT_SOURCE_HOST, CURLOPT_SOURCE_PATH, CURLOPT_SOURCE_PORT and CURLOPT_PASV_HOST added —3p-url, —3p-user and —3p-quote This release also contains many bug fixes For more information or to download, visit curl.haxx.se Check out some of the hottest new releases from PEAR File 1.1.0RC4 Provides easy access to read/write to files along with some common routines to deal with paths Also pr vides interface for handling CSV files File_Passwd 1.1.2 Provides methods to manipulate and authenticate against standard Unix, SMB server, AuthUser (.htpasswd), AuthDigest (.htdigest), CVS pserver and custom formatted password files Text_Wiki 0.25.0 Abstracts parsing and rendering rules for Wiki markup in structured plain text Net_IDNA 0.5.0 This package helps you to encode and decode punycode strings easily Net_UserAgent_Mobile 0.21.0 Net_UserAgent_Mobile parses HTTP_USER_AGENT strings of (mainly Japanese) mobile HTTP user agents It’ll be useful in page dispatching by user agents This package was ported from Perl’s HTTP::MobileAgent February 2005 ● PHP Architect ● www.phparch.com NEW STUFF Editorial Continued from Page Blogging and the Damage Done is, for all intents and purposes, cast in the Internet stone—as the Romans used to say, verba volant, scripta manent What is written in a blog “sticks” and has the potential of embarrassing a company by short-circuiting its carefully choreographed PR spin machine Is this really so bad, though? Consider this: information that goes on a blog stays on a blog Yes, it can be crawled by a spider, but, eventually, any information that’s deleted at the source will drop off search engines A posting being propagated by outside sources, such as other blogs, is a bit more problematic, but eventually even those blogs will let it go Now consider this: Google owns a collection of some ten or more years’ worth of Usenet news Ten years! Anything any one of us has ever posted on Usenet—as well as hundreds of public mailing lists—has stuck around for all this time (and is likely to stick around for a lot longer) The persistence of Usenet data, to me, is much more troublesome than blogs There are plenty of posts I’d rather I never made (go ahead search them all and post them on your blog!), but for the most part the thing that bothers me is that I never made a posting with the idea that I was creating a permanent record of my mischief On top of that, Usenet has been around for a lot longer than blogs—so there’s plenty of silliness going around for everyone In the end, the corporate world seems to be developing its usual odi et amo relationship with blogs: on one hand, they’re a great tool for public relations, while on the other they are a source of infinite frustration It’s the age-old problem of public relations: wanting as much third-party publicity as possible, which is often considered as more reliable than company-sponsored fluff, but only if the corporation is in complete control of it In my neck of the woods, that’s called having your pie and eating it, too, although I suspect someone else may use a slightly cruder term connected to the food by-products of male cattle But only on their weblog Looking for a new PHP Extension? Check out some of the lastest offerings from PECL pecl_http 0.2.0 Currently implemented features: • • • • • • Building absolute URIs RCF compliant HTTP redirects Caching by “Last-Modified” and/or ETag (with ‘on the fly’ option) Sending data/files/streams with (multiple) ranges support Negotiating user preferred language/charset Convenient request functions to HEAD/GET/POST if libcurl is available colorer 0.1 Colorer take5 is a syntax highlighting and text parsing library, that provides services of text parsing in host editor systems in real-time and transforming results into colored text For details, see http://colorer.sourceforge.net/ While colorer is primarily designed for use with text editors, it can be also used for non-interactive syntax highlighting, for example, in web applications This PHP extension provides basic functions for syntax highlighting maxdb 1.0 MaxDB PHP is an extension which provides access to the MySQL MaxDB databases It is compatible with MySQL’s mysqli extension vld 0.8.0 The Vulcan Logic Disassembler hooks into the Zend Engine and dumps all the opcodes (execution units) of a script February 2005 ● PHP Architect ● www.phparch.com FEATURE PHP Under Fire F E A T U R E by Christian Wenz When praising the vast database support that PHP provides, the products that are mentioned most often are the likes of MySQL, SQLite, PostgreSQL and MSSQL, but there are several others One database that has been rather neglected for a long time is Firebird It’s time for a closer look “ PHP & MySQL” almost sounds like a tautology, but this is a bit unfair in respect to the other databases available SQLite is a very strong contender, especially if there are many read operations and little in the way of write operations PostgreSQL gets excellent reviews, but still struggles with the market share Microsoft SQL Server (“MSSQL”) is usually only available in a heterogeneous network, but a renowned IT magazine benchmarked various web server setups (Apache, IIS, PHP, ASP.NET, MySQL, MSSQL) a couple of years ago, with Apache on Linux and MSSQL on Windows being the winning combination A DBMS that has been mostly neglected by both developers and the media is the Firebird database It all began on September 4, 1984, when former DEC employee Jim Starkey sat down and started to implement his own database server This was later pursued at Borland, and resulting InterBase turned out to be a quite successful product that was well-received by the market (even though Borland tried to rename itself with very little success) The next important step in the development of the software turned out to be July 25, 2000 The same day the fatal Concorde crash near Paris happened, Borland (then probably Inprise) took the source code of their InterBase database system and turned it into open February 2005 ● PHP Architect ● www.phparch.com source This launched a new project, FirebirdSQL, that developed the database server further based on Borland’s code The code was issued under the InterBase Public License v1.0, also known as IPL ( http://www.borland.com/devsupport/interbase/opensourc e/IPL.html), which is a variant of the Mozilla Public License Speaking of Mozilla, when the Mozilla project started working on his standalone browser, they first codenamed it Phoenix However, since there already existed a motherboard manufacturer with that name, the browser was rechristened “Mozilla Firebird.” This caused some confusion, at least according to the “Firebird-the-database” faction After some discussions, the Mozilla project changed the name of its browser to the one we now all know: Firefox (which is not a fox, by the way, but a panda—despite the logo) The Firebird database, however, kept its name REQUIREMENTS PHP 4.x , 5.x OS Linux, Max, Windows Other Software Firebird Code Directory phpfire + InterBase extension 10 Secure Communications with PHP and SSH SSL—not the same as SFTP, which we’ll look at later) is usually left out It’s just not… popular enough And why would they bother to include FTPS? Chances are they’re already running an SSH server that includes support for SFTP (FTP via SSH transport) What is SSH? SSH is not just “telnet with encryption.” Put that idea out of your head SSH, defined by the Internet Engineering Task Force (IETF), is actually a collection of protocols At its heart is a Layer binary packet transport protocol that provides extensible encryption and transmission integrity verification The transport layer uses a combination of very large primes for exchanging shared secrets, symmetric cryptography for encrypting payloads, one-way hashing for integrity checks, and optional compression Residing above this layer are an additional two protocols (referred to as services) The first is authentication, using methods such as shared secret (password), public key, keyboard-interactive, with room for custom methods to be defined by individual implementations or extension of the protocol by community consensus Nearly every layer of the SSH protocol is independently extensible without generating incompatibilities with other implementations We’ll look at an example of this later on when we select specific ciphers The second protocol residing above the transport layer is the connection service This allows a single SSH connection to establish multiple “sub-streams” (known as channels), each carrying on an independent conversation For example, a typical use of an SSH client might be to open a shell on a remote server with X11 forwarding and an additional window for file transfer In this example, we’d have at least three separate channels: one for our interactive shell, one for File Transfers (SFTP), and one or more for X11 forwarding Naturally, each of these channel types carries on its own conversation using a protocol sitting on top of the connection service Figure shows where each of these protocols FEATURE fit We’ll visit each of these layers in the next few sections to get a good feel for the theory behind SSH, then delve into some real world problems—and solutions Finally we’ll finish up by looking at some less common tasks the more esoteric side of SSH For additional details on the SSH protocol suite, refer to the IETF draft index at: http://www.ietf.org/ids.by.wg/secsh.html The Transport Layer When a client first connects to a server, they exchange banners, a short string of text declaring protocol version numbers, and the name of the protocol implementation A typical server banner might look like: SSH-1.99OpenSSH_3.9p1 This tells us that the remote server speaks SSH, with version and version compatibility, and is running OpenSSH version 3.9 portable Our client will respond to this with: SSH-2.0-libssh2_1.0 Here, a version number of 2.0 indicates that our client only speaks version of the SSH protocol, with no backward compatibility with version Once this simple greeting is done, the client and server compare specific capabilities, stating what methods they support for transport layer activities This method list includes KEX (key exchange), HOSTKEY (server identity verification), CRYPT (cryptographic ciphers), COMP (compression), MAC (Message Authentication Codes), and LANG (language preferences) The meaning of each of these methods and the means to customize them is detailed later in “Tweaking the Transport.” For now, let’s see what it takes to get the transport layer moving: That’s it! In this one line of code, we’ve established a connection to the SSH server on shell.example.com, agreed on an encryption method, exchanged encryp- Figure February 2005 ● PHP Architect ● www.phparch.com 59 FEATURE Secure Communications with PHP and SSH tion keys, and enabled secure communication for life of this connection During this exchange, the server offers its public key and proves that it has the matching private key by sending a unique, non-reusable signature PHP handles verifying the signature against the offered public key and calculates the fingerprint hash of the public key offered PHP’s responsibility stops there however While the remote server may have been able to prove that it has the private key matching the public key it offered, we haven’t yet confirmed that the public key offered actually belongs to the server we’re connecting to To that, we need to compare the fingerprint of the Listing 1 public key the server sent with a known fingerprint value Listing shows this in action By default, ssh2_fingerprint() will return an MD5 hash of the fingerprint using ASCII hexits ssh2_fingerprint() can also be instructed to return an SHA1 hash and/or raw binary values (See http://www.php.net/ssh2_fingerprint for more information) By verifying the fingerprint prior to sending any passwords, we ensure that the server we’re sending our password to is, in fact, who we think it is Otherwise, we could wind up sending our password to a stranger without realizing it and allowing them the opportunity to use that information to break into the server we’d intended to connect to and all manner of nefarious deviltry The Authentication Layer Before any self-respecting server allows us to anything to it, it’ll want us to verify our identity The simplest way to this will be to send our username and password combo Since the transport layer has already been initialized, we can rest assured that this information is being encrypted en route and won’t be privy to spying eyes If we’ve done our job of verifying the server’s identity by checking the fingerprint, then we also know that it’s not being sent to a well-placed third party Referring back to Listing 1, we see the connection, verification, and login steps in action A more exciting authentication method than passwords is public key authentication You may recall from Listing 2 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 February 2005 ● PHP Architect ● www.phparch.com 60 Secure Communications with PHP and SSH our discussion of the Transport layer that, during the connection phase, the server is required to prove its identity using a public key that is known to the client ahead of time, and a signature generated with a matching private key A third-party server residing between the client and the real server wouldn’t be able to simply reuse a signature previously fetched from the real server because the parts that go into making up the signature are unique to every connection Similarly, when using public key to authentication to a server, that server can’t use your public key signature to turn around and login to another because the unique parts of the signature would be different What this means is that, for our initial introduction, even if we don’t know the server’s fingerprint, we can send our public key signature and know that any intercepting third party won’t be able to a thing with it That’s not to say that you shouldn’t worry about verifying the server’s fingerprint if you’re using public key authentication—far from it Just know that it’s one more layer of security between you and the ne’er wells The first part of Listing shows us how to authenticate to a remote server using a public/private keypair Even if you trust the security of your server very well, it’ll be a good idea to encrypt your private key If you so, you’ll need to include the private key’s passphrase in the fifth parameter of ssh2_auth_pubkey_file() The format for public and private keys used by PHP’s SSH2 extension is identical to the formats used by OpenSSH If you use OpenSSH as your server, you can follow these simple steps to generate a key pair: $ ssh-keygen –t rsa –b 2048 Generating public/private rsa key pair Enter file in which to save the key (/home/joe/.ssh/id_rsa): Enter passphrase (empty for no passphrase): sEcReT Enter same passphrase again: sEcReT Your identification has been saved in /home/joe/.ssh/id_rsa Figure February 2005 ● PHP Architect ● www.phparch.com FEATURE Your public key has been saved in /home/joe/.ssh/id_rsa.pub The key fingerprint is: b5:bc:72:25:86:d9:a2:37:5f:01:4c:a8:88:2b:dd:02 joe@hostname If you’d prefer to use a DSA key, or a key of a different size, simply change the values used with the –t and –b options You’ll obviously want to select a more unique passphrase than sEcReT, but the rest of the options should be safe to accept the defaults for The fingerprint provided at the end is an MD5 fingerprint provided in hex (the same format used by ssh2_fingerprint() for the hostkey fingerprint) Once you have a key pair, you can pass the public key portion to all the servers you want to use it with, by appending it to /home/joe/.ssh/authorized_keys (in the case of OpenSSH), or whatever file your SSH server uses Channels The common name for any substreams managed by the connection service is “Channel.” As shown in Figure 1, there are four root channel types defined by the SSH2 protocol The first is the “Session” channel, which provides support for a number of interactive protocols including terminal shells, remote command execution, and file transfer protocols such as SCP and SFTP The next channel type, “x11” is used by traditional SSH client applications for forwarding X11 protocol requests and can be ignored within the context of a PHP application Last, but not least, are “forwarded-tcpip” and “direct-tcpip”, which corres spond to server sockets (stream_socket_server() and stream_socket_accept() ) and client sockets f (fsockopen() or stream_socket_client()) Listing includes a short conversation with an interactive shell that stops and starts Apache on the remote server by way of the sudo utility This is precisely as if we’d opened an ordinary SSH client, typed in those commands, paused for a couple seconds to read the resulting messages, and continued until finally exiting the shell and closing the window Of course, interactive shells were meant for human beings, not autonomous scripts, so instead of starting up a shell, we can issue individual commands through the use of ssh2_exec() as also shown in Listing Like with a shell, we receive a bidirectional stream to send additional data and receive responses through Because this command requires no additional input and only returns a short bit of output, we can simplify its handling by using fpassthru() to dump whatever it returned to output The last type of channel we’ll look at is the TCP/IP tunnel, which, as hinted above, comes in two flavors: ssh2_tunnel() establishes a connection channel using the direct-tcpip type to a remote host traversing through an encrypted SSH transport from client to server, then traveling unencrypted from the SSH server 61 FEATURE Secure Communications with PHP and SSH to its ultimate destination The other flavor, forwarded-tcpip using ssh2_forward_listen() and ssh2_forward_accept(), causes the remote server to listen for and accept connections on a given port and forward them back to the client To reconnect with the parallels we drew earlier, ssh2_tunnel() is like using fsockopen() or stream_socket_client() at the remote server, and using ssh2_forward_listen() / ssh2_forward_accept() is like using stream_socket_server() / stream_socket_accept() Confused? Consider Listing Here, we’ve established two separate SSH transports, one to host-a (stored in $sshA), and one to host-B (stored in $sshB) From host-a, we listen for connections on port 12345, then we establish a connection by way of host-b to host-a on port 12345, and accept the connection on behalf of host-a Subsequently, when we fwrite() over the $client_socket, our packet gets encrypted and sent securely to host-b, decrypted and sent in clear text from host-a to host-b, and reencrypted for its route back from host-a along that transport Figure shows the route taken by these packets Secure FTP and RCP The final piece of our SSH puzzle is probably also the most useful piece to an automated script: File Transfer In the world of SSH, file transfer comes in three flavors: SFTP, SCP, and crazy Raise you hand if you know what SFTP is… if you said “An encrypted version of FTP”, then shame on you, go back and read the introduction! SFTP is not FTP with encryption That’s FTPS, and while FTPS is a nice solution to the problem of encrypted file transfer files, it still suffers from several of the drawbacks of the FTP protocol For example, FTP provides very little in the way of stat() data—in fact, only the filesize element of stat can be reliably retrieved Additionally, FTP/FTPS does not allow for advanced filesystem manipulation, such as the creation and resolution of symlinks, or seeking to arbitrary locations within an open file To address these, and other limitations, the SFTP protocol was redesigned from the ground up with its own binary packet protocol designed to sit on top of the SSH transport layer protocol, and could, in theory, be used independently or with another transport A full list of the SFTP functions available within PHP can be found in the online manual ( http://www.php.net/ref.ssh2 and http://www.php.net/wrappers.ssh2), but for starters we’ll just focus on the meat of it: Transferring Files The first thing we need to in order to use SFTP is request the SFTP subsystem from the remote server Listing shows this using the preferred method (via context options), and a fairly simple fopen() and fgets() loop to output the file to the browser The PHP manual provides some shortcut methods, including the more familiar February 2005 ● PHP Architect ● www.phparch.com fopen(‘ssh2.sftp://username:passwordd@shell.exam ple.com/path/to/file’, ‘r’) you’ve undoubtedly used with http:// URLs in the past As mentioned above, SFTP offers a wide range of services related to reading and writing files as well as filesystem operations like renaming and deleting files, and adding symlinks; however, for simple file copying, SFTP is actually more power than you need Using a simpler, more lightweight protocol known as SCP, you can easily transfer whole files from your local file system to a remote server and back Once again, PHP comes to the rescue in the form of an easy to use pair of funcListing Listing Listing 62 FEATURE Secure Communications with PHP and SSH tions: ssh2_scp_send() and ssh2_scp_recv() Bear in mind that, because SCP requires knowing the source file’s size before copying it to the remote server, it cannot be used with stream sources (such as HTTP and FTP) and generally works best with files on the local filesystem If you must use SCP (perhaps SFTP is unavailable on your target server), and you must copy an http:// resource to it, first copy the http file to a temporary location on the local filesystem, then use scp to copy it up to the target server Use something like the following technique: Unfortunately, it’s entirely possible that the server you’re connecting to doesn’t support SFTP or SCP Either the system administrator deliberately disabled those subsystems, or the SSH server they’ve installed simply doesn’t support it If that’s the case, we’ll need to fallback on the third option mentioned earlier: “crazy.” At this point, I’d like to advise all seasoned programmers to turn their heads and cover their children’s eyes By making certain assumptions about our target operating system, we can sculpt cat and echo to play the parts of ssh2_scp_send() and ssh2_scp_recv() For example, the last two lines of the previous code snippet could be changed to the following: $data = file_get_contents(‘http://www.example.com/x.html’); $arg = escapeshellarg($data); ssh2_exec($ssh, “echo –n $arg > /var/www/x.html”); Similarly, we could retrieve the contents of a file through the use of cat and the ssh2.exec:// wrapper: $fp = ssh2_exec($ssh, ‘cat /var/www/x.html’); fpassthru($fp); Before you run off using this method in every script, yourself a favour and search for an alternate approach (like SFTP or SCP) They will yield much more consistent results and be compatible from server to server One last important note about SFTP file transfer is the fopen() append mode Unfortunately, the current release of OpenSSH doesn’t support append mode in its SFTP server To simulate file appending, we’ll need to use another technique from the bag of dirty tricks: nonatomic seek and write This technique involves opening a file for simultaneous reading and writing, then seek- Listing 6 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42