I just spent half an hour hunting for midnight (it's now 00:30) groccery store in a sleep-in town, searching for diet coca-cola lemon.
Am I addicted?
Recently I decided that I want to move to Subversion 1.1, and have a central repository that manages all my code. The main reason for this was that I got myself a laptop, so having a file-based repository1 that I can access from my laptop.
Being security minded person, I want to tunnel this through SSH, so nobody could look at my valuable code - I'm currently implementing bogo-sort, no less :-)
There are many easy way to do this, but I wanted to use the most direct way, which is a
Sadly, I'm not a *nix guy, so my server is going to be a WinXp Pro machine, but I could find no resource whatsoever that support it without installing Apache2 on my computer. As I mention previously, I don't like to install more than what is absolutely necessary. I want to use svnserve with SSH. It's easy to get a detailed guide on how to do it on *nix, but on windows? Compelete silence.
TortoiseSVN mentions that this is possible, but leave it as an excerise for the reader.
Here are the steps needed:
SSH Server for windows - Checked, I got OpenSSH for Windows
- Comes with an installer.
- Install client tools (or can install only them).
- Run as a service.
- Has readable quick start guide that actually works (not so sommon in software from sourceforge :-) )
Install it on the server ( as administrator)
Go to the installation directory and run the following commands (covered in the quick start guide):
Make sure to run those commands as administrator, otherwise you may get weird failures.
This assumes that you want local users & groups, for domain user & groups, run those same commands, but the "-d" paramter
- mkgroup -l >> ..\etc\group
- mkpasswd -l >> ..\etc\passwd
Run net start opensshd (again, as admin)
Be aware that the ssh server is not automatically started, so you may want to change that on services.msc
Verify that you can connect to the ssh server by issuing the following command "ssh localhost". You should get a disclaimer about accessing the system and a password prompt. Enter your password and verify that you can log in.
Now, open <OpenSSH installation directory>\etc\banner.txt in notepad and delete all the text, save and exit notepad.
The reason for this is that subversion expect only the password prompt and when it encounter the banner's content it chokes.
The next step is to issue this command "ssh localhost svnserve -t"
You should get a password prompt and a response similar to this:
( success ( 1 2 ( ANONYMOUS EXTERNAL ) ( edit-pipeline ) ) )
This means that you can connect to the repository over ssh, now all that remains is to make subversion itself talk to the ssh server.
Here we have a problem, the problem will happen in one of two cases:
- Your repository is located on a different drive then the SSH Server.
- You don't want to use paths like svn+ssh://server/path/to/repos/
So, what need to be done? svnserve (the process that implement the remote connection) accept a -r parameter that allows it to spesify a root for the repository.
The problem is that you cannot specify the -r paramter in the client, because that is hard coded. The docs say that you need to create a wrapper script around it that would set the proper parameters, The problem is that such a method doesn't work on windows, probably because of the way the SSH server attempts to run the command.
There are many ways to solve this, here is a(n incomplete) list:
- Edit $HOME/.ssh/autorized_keys2 so that whenever you log with a spesific key the SSH server will call svnserve -r x:\path\to\repos instead of the usual shell.
- Edit C:\Program Files\OpenSSH\etc\passwd so that whenever a spesific user(s) log in, they will get svnserve -r x:\path\to\repos
- Create an executable that will call svnserve properly.
I didn't go with the first option because it seems too much for me. The second option forces me to only use subversion or to use some sort of a switcher executable.
This third option took me some time to get right3, but the short version is that you can download the result here.
Download the file, extract it and put it in Subversion bin directory (default: C:\Program Files\Subverion\bin\).
Rename svnserve.exe svnserve2.exe
Rename svnproxy.exe svnserve.exe
Create a file named redirect.inf in the same directory and in it put the following:
svnserve2 -r x:\path\to\repos
Now you should've everything that you need in order to use svn client to connect to your repository over ssh.
Verify that you can use svn+ssh by issuing the following command:
svn list svn+ssh://localhost/
You should see the familiar listing of your versioned files.
Additional things you might need to do are:
- Setup a firewall rule allowing transfer from port 22 (I set it up to allow only my own subnet, but it is okay to expose it to everyone.
- You might want to add your SSH server key to the list of known keys on all the machines that you'll use to access the repository, it's not technically needed, but it would avoid getting that pesky warning about an unknown key and may avoid man-in-the-middle attacks later on.
- Set OpenSSH as an automatic server (in case you reboot and then can't find the server, that is because the SSH server is not on, you would need to manually start it using: net start opensshd
1I keep getting confused between 'repository' and 'respitory' (or is it 'respiratory') :-)
2$HOME in windows points to C:\Documents And Settings\<User Name>\
3For a full disclosure of how I solved this, go here
How to create a svn server on windows is explained elsewhere, but there is a real problem when trying to do this over ssh.
Here is how you do it.
This nessage lies the foundation to how I did it.
You need a SSH Server such as OpenSSH for Windows.
Follow the installation instructions quickstart.txt file.
Make sure that you can connect using "ssh localhost"
Now comes the tough part, svn on ssh uses the following command to connect to your computer:
ssh
This works in case you are want to access you repository like svn+ssh://server/path/to/repos
But if you want a different path, or if your repository reside on a different drive than your SSH server, you are in a problem.
You can fix this by passing the -r arguement to svnserve, but you can't do that normally because svn calls to svnserve directly.
The solution to this problem is to have a wrapper around svnserve that calls to svnserve with the correct paramters. The problem is that on windows, batch of .cmd files aren't executed when the SSH server atempts to call svnserve (this is probably a because it attempt to CreateProcess, instead of using a command interepter). So, you need an executable file that will be a warpper.
I experimented with a lot of standard input / output redirections schemes but none of them worked correctly, and I didn't want to try to solve that.
What I did finally is using the system() call in C/C++ which does exactly what I want.
So I wrote a small wrapper exe that reads from a redirect.inf file that is located in the same directory as the exe, and then run the command in the file as well as any command line parameters that were passed to it.
You can download it here (source below).
My redirect.inf file contain the following line:
svnserve2 -r D:\path\to\repos
I renamed svnserve.exe to svnserve2.exe and renamed svnproxy.exe svnserve.exe, then put both the proxy and the redirect.inf file in Subverion\bin directory and that was it, I had secured access to my repository.
Note: The following code is neither elegant nor very robust, but it does the job.
#include <WINDOWS.H>
#include <FSTREAM>
#include <IOSTREAM>
#include <TCHAR.H>
using namespace std;
int _tmain(int argc, TCHAR * argv[])
{
char str[2000];
string full;
fstream in;
GetModuleFileName(0,str,2000);
string filename(str);
int s = filename.find_last_of('\\');
filename = filename.substr(0,s);
filename += "\\Redirect.inf";
in.open(filename.c_str(),ios_base::in);
if(!in.is_open())
{
cout<<"File not open"<ENDL<<FILENAME.C_STR()<<ENDL<<<"Error: "
< return -1;
}
while(!in.eof())
{
in.getline(str,2000);
full += str;
}
for(int
i=1;i {
full += ' ';
full += argv[i];
}
return system(full.c_str());
}
The first time that I learned (rather than absorb) to program was in C++, and I liked it. I loved C++ with all its warts, the exception-aware programming, the resource allocation issues, the memory overflows, the leaks, etc. When I got .Net, I jumped on C# and didn't look back (much), I've no programmed in C++ in roughly four years.
Recently I needed to do a small application in C++, total final size 43 lines, and it took me nearly half a day. I had to unlearn a lot of stuff about .Net and relearn how to program in C++.
It took me nearly an hour to properly read from a text file, mainly because I kept trying to find the ReadLine() and ReadToEnd() and because of horrendous tool support (no ReSharper for C++, yuck!).
Anyway, I recall reading Effective C++ & More Effective C++ for fun, and Stroustrup was for bedtime reading.
I read C++ code with no problems, but I don't think that I can call myself a C++ programmer anymore, too many .Net insticts.
I'll need a refresher before I could honestly call myself a C++ programmer.
The transfer was smooth (I worry because she surf in a lot of Hebrew sites, and FireFoxused to have problems with it).
The only problem so far was with Globes' site which is radically different in FireFox than IE.
This is a me too post :-)
TestDriven.Net is now a dotOne version, and a must have tool for any serious developer.
According to Achim Ruopp, there is no support for hebrew on the command line.
The call hebrew a comlex script.
I don't know what is so complex about it, I speak it since I was three and could read when I was five years old.
I'm searching for a way to display hebrew text on the command line {cmd.exe} correctly.
There is a command, chcp that allows you to change the active code page, but it doesn't work!
c:>chcp
Displays or sets the active code page number.
CHCP [nnn]
nnn Specifies a code page number.
Type CHCP without a parameter to display the active code page number.
The code page for Windows {ISO} Hebrew is 1255, and I also tried several others {862 - DOS Hebrew, 28598 - Punctionless Hebrew, 10005 - Mac Hebrew, 65001 - UTF8} and nothing gives me the ability to see hebrew on the command line, instead, I get gibberish!
If anyone knows how to solve it, I would really like to know.