 Hey, everybody, this is Brian, and this is not a tutorial. I don't really know what to call this. I'm just going to call it a technology preview. Kind of going to go on some of the code, like I had this plug-in service. I was explaining in one of my tutorials, I think it was 100, it was 100, how we use Q plug-in, and we can create and load plug-ins. Well, one of the things I wanted to do was make this very extensible. So let me start up my little app here. And this program is very simple. I won't actually bore you with the details, but what it does is it's going to run as a Windows service, and it simply loads plug-ins. And as you can see, it says FTP server listening, telnet server listening, listening on port 1,000. So this program's whole mission in life is to just load plug-ins. I wanted to really explore what I couldn't do with the Q plug-ins. So let's just telnet into this thing. I'll go host on 1,000. And this is the application running in the background. You can see how it's just connected. I'm just going to type help. And there's a list of commands. And you've seen this before if you watched the previous tutorial. And we're not going to spend a whole lot of time on this because I want to cover some new things. If we simply type list, it will show you the plug-ins that are loaded. Now you notice how there's an FTP plug-in. What I've done is I've created three plug-ins, a launcher plug-in, which will just simply launch another program when the plug-ins loaded. And then I created a telnet plug-in. If you're wondering what telnet is, let's just find out here to create another window here. Window mania. All right, let's just go telnet. Locahost 23. We could have just left out the 23. But telnet's on port 23. And then when this connects, it'll say inner password. Now, because I wrote this and I haven't said it, I know that the password is literally P-A-S-S-W-O-R-D. That's what telnet does. It actually gives you a remote command line once you've entered a password here. So let's just do a CD, C drive, and voila. There you go. I have full, unfederated access to this computer's command line from across the TCP connection. That's what telnet does. But the point is I wrote that in Qt. So let's kill this. Let's kill that, and let's kill that. Let's just explore real quick here. If you're not familiar with Plugin Service, don't worry. We'll cover it in detail later on. But the telnet plugin is actually what I wanted to focus on a little bit. You see how it uses the interface that we've discussed previously, the plugin interface? That's how the plugin service loads this. And the guts of this thing lives in telnetplugin.cpp. Let's just kind of remove that, remove that. As you can see, it's not too difficult of a program. It just has some very basic things, like it starts a server on port 23, et cetera, et cetera. And you've got some exec commands. And that's how you set the password in the port, so you could actually set this. And what it'll do is it'll actually encrypt it or make a cryptographic hash. So when we store the password, we're not storing it in plain text. And I'll cover that in a little bit more detail later on. And then here's the TCP server. And all we're doing here is we're just saying, OK, create a Q process, and when something happens, fire it off. Actually, I think I got the wrong one here. There it is, TCP client. Sorry about that, my bad. So when the client socket connects, we're just creating a new Q process. And then we do a little bit of magic in the background, like we set a banner where we ask for the password, and we make sure they're authenticated, things like that. And then, oh yes, if we're going to change directory, I had a really hard time with that piping that Q process for some reason. So I just manually overwrote it and said, if the command buffer is CD, then we're going to actually kill a process, restart it with a new working directory, and see the set working directory neuter. That's how you do the CD command. So then I thought, well, that's nice and all, but I want to really challenge not only myself, but Qt. I want to see what this thing can do. And one of my personal hobbies is writing fully functional TCP client server. So I wrote, you guessed it, an FTP server. Now, before we begin, I'm just going to say that, let me show this, this comes as is with no expressed warranty of any kind. I'm going to release this on my website, full source code. This does follow RFC's 959, 3659, and 755. If you're wondering what that is, just go out to this link right here. And this is all in the header files, by the way. This is ftpdatasocket.h, and every header file has a link to it. And that'll go over the RFCs in detail. Actually, Wikipedia is probably a better one. And what this thing does is it is an FTP server. It has a full list of commands here, you can see. So you can upload files, download files, all sorts of stuff. It even has the newer MLSD and ML list. The problem with FTP is the normal list command, if you're familiar with this protocol. It just throws it out there in whatever the default operating system is. So if you want a list of a directory, well, it's up to the FTP client to figure out what in the world you are. So there's a different list for Linux, a different list for Unix, a different list for BSD, a different list for Mac, a different list for Windows. As you can imagine, FTP client authors go just insane trying to decode what in the world the server just sent them. So there was an RFC3695, which you see, it says Not Complete, because I did not implement the entire RFC, just these commands. MLSD lists a directory in standard format. MLSD lists a single entity. And let's kind of dive into this code a little bit. I mean, this is a pretty hefty program. It took me about a week and a half. That's why I haven't done any tutorials, because I've been just chugging away on this FTP server. There's app settings, which this just simply inherits Q settings and does some simple stuff, so you can save settings very easily. FTP's comprised of what's called a data socket and a file socket. Let me explain that a little bit better. FTP has two sockets, a data socket, which you connect on port 21. And then whenever you drag down a file or a directly listing, that goes over what's called a file socket. So you're creating a different socket. It has two modes, port and passive. Port means that the server will connect back to you. Passive means you will connect back to the server. It gets kind of complex, I know. This was developed back in the pre-dawn of the internet. I mean, literally every web server in the world is running FTP. So if you don't know what FTP is, please go buy a book. Now, get in here a little bit. You can see how I've got all these commands, and I've tried to make it simple. And there's just an ungodly amount of stuff in here. I mean, it's just, let's see if we can, wrong file. Drup. FTP data socket, here we go. I didn't like that. There we go. I mean, the list just goes right off the screen of all the functions that I had to implement here. And I tried to implement a pretty hefty amount. And then the file socket, of course, is what we used to transfer the data. And FTP list item, this is how we get a list of information. Now, what do I mean a list of information? What this does is it actually emulates a Unix server. So this will return back a directory listing in Unix format. So when the client says list, it just spits it out in this format. And then the MLS item, that's the new standardized format. Very simple, easy to understand here. And then, of course, we've got the FTP plugin, because I want this as an actual plugin. FTP port. This takes a little bit of explaining. The port command or the passive command sends a funky list of numbers. And let me actually pull up a website here. Let me pause video real quick. OK, the FTP port command. Go to Security Pros and you can just Google it. But basically, it shows you a very simple dump of what's going on. I don't know if the video is picking this up very well. But the port command will include an IP address and some really freaky numbers behind it. And what's going on here is they're actually putting the port in decimal hex format. Yes, that's a mouthful. Basically, they're converting it from decimal into hex, splitting it into two bytes, a high byte and a low byte, and then compacting those into some funky string. And then you have to merge them back together and convert it into a decimal to get the actual port number. That was not fun to implement, boys and girls. Let me tell you. Let's go into FTP port and get a kind of clear view of what's going on here. You can see this is what it'll return. And there's your IP address. And then there is the actual port number. Notice how it's two different numbers. We have to convert those. And you see I've got all the converting going on here. And then from string, we can actually pull it in and then pick it apart and convert everything. And you see I'm doing some hex converting and then set num and playing around with the bits. That took a while to figure out, because I'm not a C++ pro, as many of you would love to believe. Actually, no, I've only been writing in C++ for about a year now. Then we've got the FTP server itself, which just very simply starts and stops. And then main.cpp. This is going to be in the FTP tester program I'm going to put on my website. And the bulk of main, we should go over this. I'm just setting the organization name and domain. You'd want to do this for your own programs at your own domain and stuff like that. But then we're setting some variables here. We're setting anonymous, true, meaning I'm allowing anonymous access. Username, a password that's going to be hashed, an IP address. You have to have your server's IP addresses. One thing I hate about FTP is you have to set the IP address, because you don't know your IP address of your external interface if you're sitting internally on the network. Let me repeat that. If you're sitting in your network and you're behind a NAT-based router, once your traffic goes out beyond that router, your IP address changes. So if you send them 1010.001, once it hits that router, they're not going to be able to access 1010.001 because they're not on your local network. So you'll need your external IP address. And that's not actually my external IP address. I was actually running a test using a virtual server just to make sure this worked. Then we set our route path. And in my case, I'm just using my eDrive test folder. And this all gets shoved off into a settings file. Let me see if I can find it here. There we go. So you can see how this is what the settings file looks like. It'll have your username, your password, which is encoded. That is actually a hash value, base64 encoded. And then our route path, our IP address. And we've got anonymous true. You always want to make sure you're never storing your passwords in plain text because it's very easy to just open Notepad or Kate or whatever operating system text editor and just go in there and start messing around with it. You'd be surprised how many times I've gone in and done some kind of investigation and found just plain text passwords all over the hard drives. All right, well, without further ado, let's fire this thing up and see what it can do here. Show sidebar. So I'm going to actually set Active Project on FTP Tester, run this, and you see how it says FTP Server Listening. Now, I'm going to pull up Oracle VM Virtual Box Manager. This is just Oracle Virtual Box, very simple virtualization tool. I've created a virtual server, so let's just fire this thing up here. And I know I'm going to get some booze here from Simeon Linux gurus. But yes, for testing, I'm simply using Windows Server 2003. The reason why I'm doing this is because I had a spare license, and it's fairly quick to set up with no real jarring issues. So I've got this on a bridge connection, meaning that it's sharing my network card. Let me log in here. And the reason why I'm using a virtual machine is because I wanted to download some popular shareware applications, like bulletproof, Voyager, Acute, just to kind of show you this. I tested this across a lot of different FTP clients. Some of them behave better than others. Let me move that out of the way here. It's like, let's load up bulletproof. And you can see I've already been playing around and testing a little bit. And you can see we got in there. Current folder, AAA. Let's go up one level. And so there is my root right here. Let me pull this over a little bit more so you can see. And you can see over in our FTP server, we're actually getting the commands. And you can see CD up blank could not go to parent, print working directory, current directories root, et cetera, et cetera. So one thing I found is that not only is FTP kind of a complex protocol in itself, but FTP clients are not all the same. Bulletproof wasn't bad. It was kind of a pain in the butt to work with, to be honest with you. I'm going to tell you right off the bat, the absolute worst one, which was ironically the one I use, was Coffee Cup. Coffee Cup, actually. Let me see if I can fit it all in the little record window here. Coffee Cup, as you can see, it displays things. I mean, there's my drive, and you can see I'm actually doing things here. But you'll notice every single time you issue a command, it says quit, 221 service closing. But in Coffee Cup, it's still connected. It's not actually connected. It connects and disconnects, connects and disconnects. And I had, honestly, I like Coffee Cup software. I sold my last company to Coffee Cup, but I was really kind of surprised when I started digging into this client about how it was acting. It was just doing some really funky stuff that made absolutely no sense to me whatsoever. But anyways, to each their own, it's still a good program. I still use Coffee Cup just because, well, it's free. But I mean, when you hit Disconnect, nothing happens because you are already disconnected. And then Qtftp, there's a good one. Yeah, let's close that. Continue. Close. And uh-oh. There's my cat. She can hear me. You can see server types, use port. Qtftp, for some reason, when I go to use passive, will crash the program. I haven't quite figured out what's going on. But I set it to port, and then, of course, it just works. There's my directory listing. There's my stuff. So let's just transfer a file here. Let's just take this guy, Upload, and you can see how uploading. Because on a virtual server, uploading goes rather slow, for some reason, but downloading goes a lot faster. And then you can see how our server is just chugging away here. And you see how it's actually doing multiple threads. And the irony, of course, is that I didn't implement threads at all. This is just Qt signal slots. So it's actually asynchronous by nature, just because we're using signals and slots in Qt. Let me kill this thing. Removal, yes, I'm sure. And you can see how it disconnects everything once we did that. And I should mention, if you're working with this, there's a lot of debug info I'm spinning out here, just because I wanted to see what was going on. You'll see Q abstract socket, connected state, unknown error. Well, if it's in a connected state, you really don't have to worry about the error string. I was trying to figure out why Qt FTP's passive mode was crashing this, but I haven't really gotten to that yet. And then FTP Voyager actually surprised me. I didn't have very high hopes for this application, especially because I don't like things that just nag the heck out of you. I used to do this, where you just do nag screens, hey, buy me, buy me, and nobody bought it. I mean, it was just ridiculous. But let's close this. Close. Close. I mean, you got all these nag screens, and it just gets ridiculous. Close, close. All right, here we go. But Voyager FTP, let me get this in the actual record window here, was surprising. It was surprising just because it's so well-behaved from a client standpoint. It's got a good list of features. No, I'm not getting paid to say this. I'm just telling you my honest opinion. You can tell it to do things like use simple directory listings. You can tell it to use passive mode. You can tell it to use the new standardized MLSD slash MLSD. And actually, let me pause this real quick. Actually, if it wasn't for Rhinosoft, the people that made FTP Voyager, I probably never would have implemented MLSD and MLSD, the standardized formatting. Because out on their website, they have a very nice, including right down to the protocol level, what's going on and how it works. And in about 20 minutes, just from reading their little document, I was able to implement this in code. It was just very simple, very straightforward. So not only do I happen to like their FTP client, I really love their online documentation. It was just awesome. So if you guys are watching, hats off. But anyways, you can implement passive mode, the new formats, et cetera, et cetera. And then, of course, connect. Let's just connect to this guy. And you can see there is our FTP server right here in all its glory. And you can see we've got our downloads and stuff like that. So let's just upload coffee cup. And while we're at it, let's just download this guy. And you see how it does multiple at the same time here. Now, if you notice that one's going faster than the other, it's strictly due to file size. But it is. I assure you, running asynchronously on the server. So you can have multiple going at the same time. And of course, it is not bottlenecking our server whatsoever. And I don't have a massive server sitting here. This is just my normal desktop. But the full source code will be out on my website. Let me actually pull up my website here. It will be out on my website, voidrums.com, under source. Almost clicked downloads there. Jeez. Source. And I'll have to put, wow, I thought I had a cute category out here. Oh, I do. It's under C++ derp. There isn't much out there right now, because I've been busy with other things. But you can click C++ just to filter it out. And I'll put it under here under a telnet server, FTP server, and probably plug-in server, whatever it is. Once again, this comes as is with zero warranty of any kind. So please do not flood me with a million questions. Like, I can't get Qt FTP passive mode to work. Please help. Or what's my IP address, or things like that. I encourage you to read the comments in the source code. I try to document as I coded. But bear in mind, there are bugs with everything else. This is version one, and it's severely untested. I'm just kind of playing around in my own little lab and making it for some side projects that I got. Anyways, this is Brian. I'll welcome your questions, comments, and feedbacks. And stay tuned for more tutorials.