Own RPM package: Make symlink survive update/freshen
Friday, August 9. 2013
During my ventures in the Linux-land, I constantly package and re-package RPMs. Sometimes to introduce new functionality to existing package or to simply get a newer version that distro vendor is prepared to offer. Number of times I've created packaging to software that is not in the distro at all.
Another thing I love using are symlinks. I can have newer and older package of a software and can simply switch with updating the symlink into correct version. When I combined those two, it bit me in the ass.
I had quite simple script-blocks to handle the symlink:
%post
cd /my/package/directory/
%{__rm} -f my.cool.symlink-name
ln -s package/library/my.cool my.cool.symlink-name
%preun
%{__rm} -f /my/package/directory/my.cool.symlink-name
On install, that worked, but on update/freshen there was no symlink left. I was puzzled, why is that? Little bit of googling revealed two pieces of information: RPM spec-file documentation about scripts, especially the Install/Erase-time Scripts -part and 2nd the Fedora Project's packaging information, especially the scriptlet ordering. I'll abbreviate the Fedora's ordering here omitting the non-interesting parts:
- %pre of new package
This is the part where my script confirms that the symlink exists. - (package install)
- %post of new package
- %preun of old package
During update/freshen, this is the part where my script removes the symlink created in 1.)
Crap! - (removal of old package)
- %postun of old package
Further reading of RPM spec-docs said "the argument passed to version 1.0's scripts is 1". Ok, nice to how, but now what? How can I utilize the information? What is the exact syntax for the script? The only usable information I found was in the Fedora packaging instructions, there was an example:
%preun
if [ $1 = 0 ] ; then
/sbin/install-info --delete %{_infodir}/%{name}.info %{_infodir}/dir || :
fi
So this was the thing I had to try. My solution is to change the %preun-block:
%preun
if [ $1 -lt 1 ] ; then
# This is really an un-install, not deleting previous version on update
%{__rm} -f /my/package/directory/my.cool.symlink-name
fi
I did that and upgraded the package. Poooof! The symlink was gone like there was no change at all. WHY? I upgraded the revision number of the package and upgraded again. NOW it worked! Nice.
There is a simple explanation what happened. It says in the Fedora project's order-list that "%preun of old package". OLD package! It works starting from the next update, but not on the first one.
Anyway I was delighted to get that one sorted.
Running Linksys E4200 access point
Thursday, August 8. 2013
I got one of Linksys wireless access points. The original idea was to install Linux into it with DD-WRT, but the operation failed miserably due the fact, that there are actually two kinds of E4200 APs. Guess who has the "wrong" kind. That would be my 3rd Linksys wireless access-point. I love their products due to extensive Linux-support and very high quality hardware. Now it looks like, this one didn't turn out like I planned.
Anyway, the thingie had a very old firmware and I thought that it would be a good idea to upload the newest factory firmware into it. That failed immediately, all I got was a "Image File Is Incorrect" error message. The message was spat out from the GUI almost immediately, so I decided to debug it. Here is the code I found:
var len = F.file.value.length;
var ext = new Array('.','i','m','g');
if (F.file.value == '') {
alert(fwupgrade.upgradefile);
return false;
}
var IMAGE = F.file.value.toLowerCase();
for (i=0; i < 4; i++) {
if (ext[i] != IMAGE.charAt(len-4+i)){
alert(hupgrade.wrimage);
return false;
}
}
Nice! The manufacturer designated file of FW_E4200_2.1.39.145204.SSA hardly matches the required .img file extension. Also on the code side: is the way of checking for the file extension completely braindead, or is it just me? Guess what would happen, if the filename would contain less than 4 characters.
It was safe to rename the file and upload the firmware. It didn't brick the thing. There seems to be plenty of people having the same issue. The unit seems to have interesting ports open, nobody knows why. Here are the port scan results:
Starting Nmap 6.25 ( http://nmap.org ) at 2013-08-07 13:47 EEST
Nmap scan report for 192.168.1.1
Host is up (0.0017s latency).
Not shown: 992 closed ports
PORT STATE SERVICE
53/tcp open domain
80/tcp open http
139/tcp open netbios-ssn
443/tcp filtered https
445/tcp open microsoft-ds
8083/tcp open us-srv
49152/tcp open unknown
49153/tcp open unknown
MAC Address: 58:6D:8F:GG:2G:3G (Cisco-Linksys)
Nmap done: 1 IP address (1 host up) scanned in 1.32 seconds
There is a project to get Linux running on Marvell-chipsets also, but the site seems to be down. So, I'm linking the WikiDevi page instead: http://wikidevi.com/wiki/Linksys_E4200_v2
Hopefully that pans out and there will be support for DD-WRT some day.
Upgrading into SplashID password vault version 7 and the security of using one
Wednesday, August 7. 2013
My weapon-of-choice for storing passwords has been SplashID for ages. I cannot even remember which version was the first I installed into my Nokia running a S60 operating system.
Yesterday SplashData went into version 7. I've been wondering what they have been doing, since there has been no minor updates for a year or so. Couple of weeks ago they informed that version 7 is coming out and hang tight to wait it to be released.
For an existing user like me, the news was pretty good. It was a free upgrade! Yes. I could get new stuff without paying anything for it. To tell you the truth, I was mighty sceptical. Their track-record of getting things right is not the best one there is. Back in the days, Elcomsoft did a study about password management software, and SplashID wasn't in the winning side there. It is generally a very bad idea to store everybody's passwords using password "g.;59?^/0n1X*{OQlRwy". Sure it is very difficult to guess, but what would happen if you don't have to guess. All you have to do is get somebody's password vault, and it pops open using that password with a blowfish. The end result is unencrypted SQlite-database.
People at SplashData did listen. They did fix the issues pointed out by those nice white-hat guys. That is a very good display of morale from the company's side. Still today, there are so many corporations who simply laugh at security investigators. For example this is one of the recent ones, the Japanese toilet manufacturer Lixil ignores Trustwave's findings, so there is nothing else to do than go public with the findings.
Fortunately my scepticism (read: pessimism) didn't pan out. I upgraded my Desktop-edition on my Windows, it activated using my existing credentials. iPhone-edition upgraded automatically from the App Store, and also activated after my Desktop-edition was activated. My iPad-edition didn't upgrade automatically, I used the normal iTunes sync and clicked there to install the already existing app into my iPad also. On version 6, there were separate versions for iPhone and iPad, now there is only a single app, which is a much better way to go on user perspective. So, no glitches there. Everything works, WiFi-sync works.
Now they offer an option to sync to cloud. To my mind, that's insanity! It is the popular way of today, but I'd never do that. Ever. The inquisitive minds already are questioning Google and their mobile platform Android about password storage. There is no difference between KeePass or Firefox Sync to mention few of those password storage providers. You'd be handing them all of your most valuable items, your passwords, to store and use. When it comes to Google and Android, they don't encrypt your data, with Apple's iOS you at least have the option of doing so.
My final words to people at SplashData: Keep up the good work!
Handling /var/run with systemd
Tuesday, August 6. 2013
Previously I've studied the init.d replacement systemd.
Update 4th Jun 2017: See the new version
To my surprise, my contraption from the previous article didn't survive a reboot. WTF?! It turned out that in Fedora 19 the /var/run/
is a symlink into /run/
which has been turned into tmpfs. Goddamnit! It literally means, that it is pointless to create /var/run/<the daemon name here>/
with correct permissions in RPM spec-file. Everything will be wiped clean on next reboot anyway.
So, I just had to study the systemd some more.
This is my version 2 (the Unit
and Install
-parts are unchanged):
[Service]
Type=forking
PrivateTmp=yes
User=nobody
Group=nobody
# Run ExecStartPre with root-permissions
PermissionsStartOnly=true
ExecStartPre=-/usr/bin/mkdir /var/run/dhis
ExecStartPre=/usr/bin/chown -R nobody:nobody /var/run/dhis/
# Run ExecStart with User=nobody / Group=nobody
ExecStart=/usr/sbin/dhid -P /var/run/dhis/dhid.pid
PIDFile=/var/run/dhis/dhid.pid
The solution is two-fold. First an ExecStartPre
-directive is required. It allows to run stuff before actually executing the deamon. My first thing to do is create a directory, the minus sign before the command says to ignore any possible errors during creation. The target is mainly to ignore any errors from the fact that creation would fail due to the directory already existing. Anyway, all errors are ignored regardless of the reason.
The second command to run is to make sure that permissions are set correctly for my daemon to create a PID-file into the directory created earlier. That must succeed or there will be no attempt to start the daemon. chown
ing the directory will fail if the directory does not exist, or any other possible reason.
Sounds nice, huh? Initially I couldn't get that working. It was simply due to reason, that the entire Service
-part is run as the user pointed by the User=nobody
and Group=nobody
-directives. That user was intentionally chosen, because it has very limited permission anywhere or anything. Now it cannot create any new directories into/var/run/
. Darn!
This where the solution's 2nd part comes in. Somebody designing the systemd thought about this. Using the PermissionsStartOnly
-directive does the security context switch at the last moment before starting the daemon. This effectively changes the default behavior to allow running Service
-part as root, except for the daemon. Exactly what I was looking for! Now my daemon starts each and every time. Even during boot.
Another thing which I noticed, is that when I edit a systemd service-file, the changes really don't affect before I do a systemctl --system daemon-reload
. It was a big surprise to me, after all in traditional init.d everything was effective immediately.
PS.
Why cronie does not create a PID-file? I had an issue in CentOS where I had not one, but two cron-daemons running at the same time. This is yet another reason to go systemd, it simply works better with ill-behaving deamons like cronie.
QNAP Turbo NAS "Error message volume full"
Monday, August 5. 2013
5 am this morning I woke, because a thing was beeping somewhere. The sound was quite annoying, so I had to investigate. My NAS-box chose to go into error state during regular backup schedule and inform me with this audible alarm, that hard drive was full. Bullshit! I said.
In the front-panel there was a flashing message "Error message volume full". However, the hard drive was far from being full. With the text, I googled into this article about QNAP HDD full. The clue about Network Recycle Bin was helpful. The system information really said, that all of the available hard drive capacity was taken. Majority of the stuff I had there was files in the Network Recycle Bin.
The fix was easy: I reduced the file retention time into half of the previous and clicked "Empty". The box chewed the drives for a couple of minutes and new stats were much better. Also the annoying beep ended.
Falling back to sleep at 5:30 was another thing. No could do. Unfortunately.
How not to behave as a member of software project
Friday, August 2. 2013
This is about how NOT to behave, writing about the opposite, how to behave, is way beyond me. I don't even know that myself. However, during my years in various companies and multitude of software projects, I've met lot of people. Some working quite effectively as members of a software project than others (best-of-the-best, if borrowing a quote from the movie Men in Black is allowed), and then there are the worst-of-the-worst. Today I share a story of such project member.
There is this project where I've been working as a contractor for almost 5 years now. There were some changes in the organization and I thought now would be about the time for me to do something else for a while. I discussed this with management, gave my notice and they started looking for new contractor, whom I promised to train before I leave.
Everything was fine until for my sins they gave me one (if borrowing a quote from the movie Apocalypse Now is allowed).
In the beginning it was pretty standard operations. My manager said, that there would be this new guy and he needed access to source code and ticketing. Pretty soon the new guy contacted me and asked for the credentials. I told him to hang tight so that I'd create a personal LDAP-account for him. I created the account, put in the needed groupings for a software developer -profile and handed them out to him. Nothing fancy there. Nothing that you wouldn't expect to see or do when arriving to a new assignment.
The next day he said something like "his code isn't that wonderful" to a colleague of mine. Naturally my colleague pretty soon told me what had happened. We've been working in the project together for a while and it was pretty normal reaction of him to say that the new guy is dissing your code there. I confronted the new guy and said that "Come on! We're supposed to be working together, why would you dis my work there." He surely knew how to set the initial impression.
A couple of days passed by and my colleague comes to me again: "Did you see, that he posted his LDAP-account username and password to a public bulletin board?" There is so little to do in such a situation, except OMG!! and WTF!! Why would anybody do anything like that. This is yet again one thing way beyond me. Sharing your personal credentials with other people is grounds for termination of employment!
I don't know what's going to happen next. I informed my manager that I absolutely positively won't be working with this guy. He's obviously not qualified for this job and will most likely do more harm than good for the company. However, I've been getting a lot of visitors for my LinkedIn profile lately from his connections. Looks like I've made lot of new fans for my Fan Club. Perhaps the confidentiality agreement doesn't apply to all of us? It is generally a bad idea to blabber about company's internal things with your contacts.
To recap:
- Don't criticize your colleagues' work behind their backs.
- If you absolutely need to criticize somebody's work, do it at him/her.
- Don't share passwords with anybody, they are meant to be kept secret.
- If you really know that a password can be shared, or you have permission to do so, then it's ok. When in doubt, don't do it.
- Don't blabber internal company or customers' issues to your friends.
- If you must do that, make sure you won't be caught doing so. When you get caught and get fired, remember I told you so.
- Take responsibility of everything you say and do. Really, that means about everything.
- This is much easier, when you say and do things people would expect somebody to say and do. If you go beyond the socially acceptable envelope, be prepared to take some heat for it.
- Then again, if you code looks like shit and works like shit, some people will
call it shit. If you cannot quantify the results of your own work, then
you're in shit. It is very unlikely that your work is the best there
is. If you intentionally write code like shit and people call it shit, don't be surprised.
Internet Explorer 11 adventures
Wednesday, July 31. 2013
I've been using a Windows 8.1 preview for a while and being a web developer, I stumbled into couple of noteworthy issues with IE 11. See my previous entry about Win 8.1.
User-Agent string
There are pretty much 2 variants:
Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.3; WOW64; Trident/7.0; .NET4.0E; .NET4.0C)
or:
Mozilla/5.0 (Windows NT 6.3; WOW64; Trident/7.0; rv:11.0) like Gecko
The only way I could get the "like Gecko" -mode enabled on a XHTML 1.0 -site, was from developers tools in the Edge-mode. My site also has a <meta http-equiv="X-UA-Compatible" content="IE=9" /> in it, but removing or adding the tag does not seem to have any effect. I'm guessing, that Edge-mode works out-of-the-box only in HTML 5. The important thing to not here is, that IE 11 declares itself as a IE 7.0, but unlike a "real" IE 7, this has Trident rendering engine 7.0. Also there is declaration of a "real-version" or rv:11.0.
Emulating previous browser versions
Gone. The good thing is that F12 developers tools have been completely re-written, but it is impossible to get the classic standards selection. I found two discussions about that. First is from superuser.com and second from stackoverflow.com.
Microsoft's idea is to go to http://www.modern.ie/en-us/virtualization-tools and use their virtualization service / tools to use a proper old browser. My advice would be: just ignore anybody using the ancient crap. I'd draw the line on IE 9, it still is pretty popular browser, but on my statistics anything older than IE 8 are totally gone.
Getting Zend Framework 1 to detect IE 11 properly
On my projects I have the ZF 1 running. I've been using Browser Capabilies Project's browscap.ini on PHP. It has solid integration into ZF 1. The bad thing is that BCP is not well maintained anymore due to key persons losing interest into maintaining one. Anyway, here is my patch into 5020:
--- php_browscap.ini.orig 2013-07-31 16:20:08.749140271 +0300
+++ php_browscap.ini 2013-07-31 16:24:14.563058655 +0300
@@ -31179,6 +31192,64 @@
Platform="WinNT"
Platform_Version=3.1
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; IE 11.0
+
+[IE 11.0]
+Parent=DefaultProperties
+Comment="IE 11.0"
+Browser="IE"
+Version=11.0
+MajorVer=11
+MinorVer=0
+Beta=true
+Win32=true
+Frames=true
+IFrames=true
+Tables=true
+Cookies=true
+BackgroundSounds=true
+JavaScript=true
+VBScript=true
+JavaApplets=true
+ActiveXControls=true
+CssVersion=3
+
+[Mozilla/*(Windows NT 6.1*64*Trident/7.0; rv:11.0*)]
+Parent=IE 11.0
+Platform="Win7"
+Platform_Version=6.1
+Win32=false
+Win64=true
+
+[Mozilla/*(Windows NT 6.1*Trident/7.0; rv:11.0*)]
+Parent=IE 11.0
+Platform="Win7"
+Platform_Version=6.1
+
+[Mozilla/*(Windows NT 6.2*Trident/7.0; rv:11.0*)]
+Parent=IE 11.0
+Platform="Win8"
+Platform_Version=6.2
+
+[Mozilla/*(Windows NT 6.3*Trident/7.0; rv:11.0*)]
+Parent=IE 11.0
+Platform="Win8.1"
+Platform_Version=6.3
+
+[Mozilla/*(Windows NT 6.3; WOW64*Trident/7.0; rv:11.0*)]
+Parent=IE 11.0
+Platform="Win8.1"
+Platform_Version=6.3
+Win32=false
+Win64=true
+
+[Mozilla/*(Windows NT 6.3; Win64*Trident/7.0; rv:11.0*)]
+Parent=IE 11.0
+Platform="Win8.1"
+Platform_Version=6.3
+Win32=false
+Win64=true
+
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; IE 10.0
[IE 10.0]
The 2nd glitch is that ZF 1 heavily relies on seeing string "MSIE" in the UserAgent identification to determine, that we're talking about Internet Explorer. IE 11 doesn't state that anymore. It want's to be like Mozilla's Gecko-engine, and happily says so. My patch for ZF 1:
--- library/Zend/Http/UserAgent/AbstractDevice.php.orig 2012-11-16 17:23:41.000000000 +0200
+++ library/Zend/Http/UserAgent/AbstractDevice.php 2013-07-31 13:58:15.422657840 +0300
@@ -512,6 +512,19 @@
} elseif ($product == 'mozilla' && $result['browser_version'] < 5.0) {
// handles the real Mozilla (or old Netscape if version < 5.0)
$result['browser_name'] = 'Netscape';
+ } elseif ($product == 'mozilla' && isset($result['comment']['full']) &&
+ preg_match('#^([^;]+);.+Trident/(.+);\s+rv:(.+)#', $result['comment']['full'], $real)) {
+ // MSIE 10+ in native mode.
+ // In emulation mode, will match MSIE 7.0
+ $result['browser_name'] = "MSIE";
+ $result['browser_engine'] = "MSIE";
+ $result['browser_version'] = $real[3];
+ $result['browser_token'] = 'MSIE ' . $real[3];
+ if (isset($result['others']['full'])) {
+ $result['compatibility_flag'] = $result['others']['full'];
+ unset($result['others']);
+ }
+ $result['device_os_token'] = $real[1];
}
/** windows */
@@ -523,6 +536,8 @@
if (strpos($result['device_os_token'], 'Win') !== false) {
$windows = array(
+ 'Windows NT 6.3' => 'Windows 8.1',
+ 'Windows NT 6.2' => 'Windows 8',
'Windows NT 6.1' => 'Windows 7',
'Windows NT 6.0' => 'Windows Vista',
'Windows NT 5.2' => 'Windows Server 2003',
That makes ZF 1 react alike for IE 11 and all other versions before that. I did test that on IE 8, IE 9, IE 10 and IE 11. Also I confirmed that to function with IE 10 and IE 11 in IE 7 emulator mode.
64-bit process
Normally I run only 64-bit browsers. Google's crappy Chrome won't do that, so I try to stay away from it. Firefox has excellent spin-off project of CyberFox, most IE versions have 64-bit counterparts, Opera has 64-bit version. The thing with 64-bit browsers is that there are a number of exploits for browsers which are tailored to run on 32-bit processes.
Anyway, the story is that on Windows 8 and Windows 8.1 the tile-mode IE is always 64-bit, but desktop-mode is always 32-bit. Ghacks.net has a story about getting IE 10 in Windows 8 to run 64-bit in desktop-mode, but I fail to confirm the results.
On IE 11 I found a setting of "Enable 64-bit processes for Enhanced Protected Mode":
... I don't know how it should affect the browser behaviour. I'm still getting:
The root-process of IE seems to be 64-bit, but anything with a real web-page in it, is always 32-bit on desktop side. Tile-mode looks like this:
So, no avail for me. Any ideas are welcome.
Un-boxing Leap Motion
Tuesday, July 30. 2013
A FedEx guy dropped my Leap Motion while I was on holidays. Today I managed to un-box it.
Here are the pics:
On the end of the thing, there is an USB-3 connector. Inside the box is a shorter cable and a longer cable, with length of 1,5 meters. The spec says USB-2 will do it on your computer.
Here are the videos:
What can this be used for? I dunno (yet).
Ran out of luck (and fuel) in Hill Climb Racing
Monday, July 29. 2013
The game has been reviewed as a major time suck. Don't get me wrong, the game doesn't suck, it just sucks my (and 70 million other players') time.
I was playing with my iPad and in Desert-stage and managed to land on front wheel with a motocross bike. The trouble was, that it was evenly balanced. It wouldn't fall on either side, it just stuck there no matter what I did. Eventually I just run out of fuel. See the pic!
Darn! No new record for that attempt.
Sybase SQL and Microsoft SQL connectivity from Linux with FreeTDS library using IPv6
Monday, July 22. 2013
Microsoft SQL server is a fork of Sybase SQL server. This is because their co-operation at their early stages during end of 80s and beginning of 90s. For that reason the client protocol to access both servers is precisely the same TDS. There is an excellent open-source library of FreeTDS to access these SQL-servers from Linux. According to me and number of other sources in The Net, this library can also access Windows Azure SQL server.
During my own projects I was building a Linux-image for Azure. My development boxes are spread around geographically, and in this case the simplest solution was to open access into a firewall to allow incoming IPv6 TCP/1433 requests.
My tests with this setup failed. IPv6-access was ok, firewall was ok, a socket would open without problems but my application could not reach my development SQL-box. Bit of a tcpdumping revealed that my Hyper-V hosted Linux-box attempted to reach my SQL-box via IPv4. What?! What?! What?!
A quick browse into FreeTDS-code revealed that it had zero IPv6-related lines of code. According to Porting IPv4 applications to IPv6, there should be usage of struct sockaddr_in6 and/or struct in6_addr. In the latest stable version of FreeTDS there is none.
After a lot of Googling I found a reference from FreeTDS developers mailing list that in January 2013 Mr. Peter Deacon started working on IPv6-support. Naturally, this was good news to me. Another message in the ML said from February 2013 said that the IPv6-support would be working nicely. Yet another good thing.
Now all I had to do is find FreeTDS source code. I found somebody's Subversion copy of it, but with Google, no avail. The IPv6-patch nowere to be found, nor the actual source code. The mailing list itself seems to be having some sort of technical difficulties. My attempts to ask for further information seemed to go nowhere. I pretty much abandoned all hope when Mr. Frediano Ziglio was kind enough to inform me that the IPv6-support would be in the latest GIT-version of FreeTDS.
FreeTDS source code can be found from Gitorious at http://gitorious.org/freetds/freetds
I can confirm that the current Git-version does work with IPv6. However, for example PHP's PDO or Perl's DBI do not support entering IPv6-addresses into connect string. With FQDN I could confirm everything being IPv6 from Wireshark, but all my attempts of entering native IPv6-addresses into connect strings failed on both libraries and FreeTDS's CLI-tool tsql.
Anyway, here is what I did to test the thing. First I confimed that there is basic connectivity:
tsql -H myownserver.here -p 1433 -U sa
Password:
locale is "en_US.UTF-8"
locale charset is "UTF-8"
using default charset "UTF-8"
1> sp_help MyCoolTable
2> go
1> quit
Then I took a simple example from Perl Monks site and modified it to work (the original code was quite crappy):
#!/usr/bin/perl -wT --
# vim: tabstop=4 shiftwidth=4 softtabstop=4 expandtab:
use DBI;
use Data::Dumper; # For debugging
use strict;
use utf8;
my $dsn = 'DBI:Sybase:server=myownserver.here;database=MyCoolDatabase';
my $dbh = DBI->connect($dsn, "sa", 'lemmein!') or
die "unable to connect to server. Error: $DBI::errstr";
my $query = "SELECT * FROM MyCoolTable";
my $sth = $dbh->prepare($query) or
die "prepare failed. Error: $DBI::errstr";
$sth->execute() or
die "unable to execute query $query. Error: $DBI::errstr";
my $rows = 0;
while (my @first = $sth->fetchrow_array) {
++$rows;
print "Row: $rows\n";
foreach my $field (@first) {
print "field: $field\n";
}
}
print "$rows rows returned by query\n";
Also I did some complex testing with PHP DBO and had no issues. I even made sure from my firewall settings, that I could not accidentally access the SQL Server via IPv4. It just works perfectly!
If you need my src.rpm or pre-compiled packages, just drop a comment.
SMScaster.com spam / scam
Sunday, July 21. 2013
This was the first time ever I got a SMS spam. It said:
Visit us at SMSCaster.com for FREE ! You have Won £2,500,000.00 Pounds (GBP). Email: eurodraws23@hotmail.co.uk with your name, phone number and claim code:EU2k1
Sender: +34603147561
My initial WTF was: What the hell is SMSCaster? Apparently it is SMS-spammers weapon of choice. A piece of software which can spit out a lot of garbage using your mobile phone connected to your PC.
Then again with Google, I found two instances of people complaining about the same thing. 1) from Australia and 2) from USA. Looks like SMSCaster is only means to an end, it is the utility doing the nasty stuff.
My second WTF was: Why an earth somebody in Spain (+34) wants to claim, that I have won money there? I tried doing a reverse phone number lookup, but there seems not to be any of them available.
Spain seems to be the primary source of Nigerian scam or 419 scam nowadays. Some journalists have followed up on some e-mail spam and they seem to originate from Spain. Also there are news, that Spanish officials have arrested suspects running a Nigerian scam ring.
Hyper-V
Wednesday, July 17. 2013
I was fiddling with a virtual machine and eventually messed it up. My fail made the Linux un-bootable and after a swift assessment I decided to extract the application data and re-install the OS. During my re-install I wanted an expanding virtual disk. As a default Hyper-V Manager creates fixed-size disks, but as my machine is not disk-I/O -dependant, I wanted to consume disk space to make my transfers easier.
Discarding the previous disk and creating a new dynamically expanding one wasn't the hard part. After I attempted to boot my machine for install I got into trouble. The darn thing wouldn't boot! The error text said: "Microsoft Emulated IDE Controller (Instance ID -blah-blarh-blaa-): Failed to Power on with Error 'General access denied error'. IDE/ATAPI Account does not have sufficient privilege to open attachment."
This type of error is widely documented. For example in Microsoft Support Knowledge base Article ID: 2249906. However, they fail to mention how to extract the virtual machine ID. Petri IT Knowledgebase has an article how to get that Get Hyper-V Virtual Machine Process ID and GUID. However, that fails to mention where the virtual machine description files are located at.
After all this research I still didn't have much to go on. Based on the petri.co.il-article, I made a search for files on my computer and deduced the path to be C:\ProgramData\Microsoft\Windows\Hyper-V\Virtual Machines.
Now that I had the virtual machine ID, I made an observation about the file's permissions. In the Microsoft KB-article they instruct you to grant full access -permission for the virtual machine. On my computer the other virtual drives have only read and write access. See this pic:
Full access sounds like an overkill anyway, I think R/W should do the trick in this case. This is what I ended up doing in PowerShell:
C:\Windows\System32\icacls.exe `
"C:\Users\Public\Documents\Hyper-V\Virtual hard disks\CentOS-V.vhd" `
/grant "NT VIRTUAL MACHINE\90DBD878-001C-412B-A668-D5BC8311C12E:(R,W)"
Now my machine boots into install.
RTMPDump core dump
Monday, July 15. 2013
Occasionally I like to stea.... erhm.... listen to stuff from Finnish Broadcasting Company's internet-site. Most of the items they have there have some sort of limit, for example 7 days or 30 days, after which the show if off-the-air for good. The technology they're using is streaming FLV, or RTMP, making it relatively easy to steal... ermhm... borrow.
On my Fedora 19 my favorite utility for doing the ste... well... stream-redirection is YLE-DL. It is a Python-wrapper for the classic RTMPDump-utility. The Python-thingie is very much needed, as the parameters required for RTMPDump can be for example:
--playpath=mp3:areena/fi/52/52cf454f9e444f498352f65cfe7ba11d \
--swfUrl=http://areena.yle.fi/static/player/1.2.8/flowplayer/flowplayer.commercial-3.2.7-encrypted.swf \
"--app=ondemand?_fcs_vhost=cp157366.edgefcs.net&auth=eb.bEdRbFdlamabdgckdRcxdvaGbxdvbZbWbscycAdcdKbncbcpbIdSdgdLbidebVbx-br5atj-c0-vga-oxmCrAxmpvkzsqrzxlzp-kblXn9lakal5nTlfn2k6kRnZ&aifp=6&slist=areena/fi/52/52cf454f9e444f498352f65cfe7ba11d" \
--pageUrl=http://areena.yle.fi/radio/1943628 \
--rtmp=rtmpe://cp157366.edgefcs.net/ondemand \
"--tcUrl=rtmpe://217.212.252.204/ondemand?_fcs_vhost=cp157366.edgefcs.net&auth=eb.bEdRbFdlamabdgckdRcxdvaGbxdvbZbWbscycAdcdKbncbcpbIdSdgdLbidebVbx-br5atj-c0-vga-oxmCrAxmpvkzsqrzxlzp-kblXn9lakal5nTlfn2k6kRnZ&aifp=6&slist=areena/fi/52/52cf454f9e444f498352f65cfe7ba11d" \
-o "Parasta ennen! pe klo 20.00-2013-07-12.flv"
This nice script does all that for me. Except it doesn't work. It just says "Segmentation fault (core dumped)". Which is rather bad.
After very short period of GDBing, I realized that some function-API changed drastically. In this case it is Diffie-Hellman -function in the GnuTLS-library, which RTMPDump can use if chosen to do so. The API-changed for example in gnutls_calc_dh_secret()-function:
Old:
bigint_t
gnutls_calc_dh_secret (bigint_t ret_x, bigint_t g, bigint_t prime)
New:
int
gnutls_calc_dh_secret (bigint_t ret_y, bigint_t * ret_x, bigint_t g, bigint_t prime,
unsigned int q_bits)
Since that function is not in the GnuTLS public API, developers of RTMPDump had to declare that function in their code to make it work. That is because gcrypt and GnuTLS are using multi precision integers to process public-key -stuff. It is much easier to multiply two huge numbers with a suitable library. In this case the libraries should be compliant with each other, but ... Having void-pointers makes it compile, but it doesn't make it run. Without core dumps, that is.
The solution is not to use GnuTLS, which seems to be the default. I chose to use OpenSSL-functions instead. That builds and runs.
Tip:
To get a core dump in Fedora 19 the automatic bug reporting tool ABRT needs to be tweaked. As a default it gets all the cores, not you. See /proc/sys/kernel/core_pattern, which out-of-the-box has value of |/usr/libexec/abrt-hook-ccpp %s %c %p %u %g %t e
So it is a very good idea to edit the value of DumpLocation-directive in /etc/abrt/abrt.conf. I put it like this and created the directory:
MaxCrashReportsSize = 0
DumpLocation = /var/spool/abrt
Then I could get a directory like /var/spool/abrt/ccpp-2013-07-15-17\:30\:42-7463/ containing a coredump-file with the exact point of the crash.
Adding dynamic IP-address support into Parallels Plesk Panel 11 DNS
Wednesday, July 10. 2013
I've been a long-time user of Parallels Plesk Panel. It really is the best product for maintaining a hosting-server. However, it is lacking the support for domain owners to update their dynamically changing IP-addresses into the panel's DNS-zone automatically.
Since I really needed such a service, I built one from parts. The central piece is DHIS client/server -software. I don't know why they stopped distributing the server-component source code, but I still have it. The license in the software is very liberal, so it can be used by anybody for anything.
As default, DHIS only supports DNS TSIG updates. That is not a good idea in Plesk, since master database for DNS-records is in the MySQL database. Also, getting BIND to refresh a zone really requires a root-access. Nobody wants to run their daemons as root, so I did two things: I added possibility of doing updates with an external script and wrote such a Perl-script to interface with Plesk's RPC API to update DNS-records.
My work is distributed here: http://opensource.hqcodeshop.com/dhis/
As the next step, I'll be investigating how to get any support for this into Plesk's GUI. It really would be nice to allow client to generate his own QRC-authentication keys instead of me doing it manually.
Formlife scam aka. health-c-p.com
Tuesday, July 9. 2013
The classic Formlife-scam popped up again. This is widely documented by authorities around the world. For example Finnish Competition and Consumer Authority have two articles about Formlife ja Vital Nordic (in Finnish): Kuluttaja-lehti 2/2013 about number of Formlife complaints and bulletin about Corex and Life Detox products from May 2012.
Formlife-scam has very simple modus operandi: They lure you in, from example from Facebook ad like this: and you end up in a web page. In this case the web page is http://wnmobile.com/fin/. In the page there is lot of health-related stories about how good their product is including customer testimonials. In the page they offer you an opportunity to purchase a sample package with 4 €. The price is not too bad, unsuspecting victims enter their credit card details and submit the order for a sample. Since I don't think that web site will survive very long, I have the web page as a PDF here. http://wnmobile.com/fin/ as a PDF
That scam-site of wnmobile.com is hosted by liquidweb.com in Lansing, Michigan, USA. It is obvious, that Network Solutions, Inc. has nothing to do with this scam. They simply are a hosting company.
Nowhere in their page they reveal anything about Health-C-P, nor Formlife, nor any of those already "burned" words. When postal services deliver the "sample" package, it does not contain a sample, but the full product, actually two separate products. Also it appears that they billed your credit card twice for the amount of 165 €. A shipping manifest will look like this:
It clearly states the fact that you have been scammed! They even mention, that your next shipment will arrive in a three months time. I don't think that they are that consumer oriented, and I strongly suspect that the next shipment will never arrive. If it will, they'll charge you for another 330 €.
The sender address of shipment is:
Health Care Payment
Postboks 313
9100 Aalborg
Denmark
According to GoDaddy domain information, the domain of health-c-p.com is registered to:
Anders Dahl Pallesen
Health Care Payment
Lyngby Hovedgade 10
2800 Kongens Lyngby
Denmark
The above address is real. Such an address exists, but I have no means on verifying what is in the building there. These two addresses are 400 km apart. The ownership of domain wnmobile.com is protected by WhoisGuard and cannot be accessed without government official involvement.
Company site of Health-C-P is (as you can expect) a rush job. In the bottom of the page it also has the address of Lyngby Hovedgade 10.
It breaks often. Especially when you try to access their customer service.
It is alwo worth noting that their customer support number of +44 203 598 2170 is in UK. It was operational when I called it, but it contained a recording saying that their "customer support is under maintenance and nobody can answer the call". The website of health-c-p.com is hosted by Hetzner Online AG in Gunzenhausen, Germany. Hetzner Online is well known for two things: cheap hosting of websites/e-mail/shell and ton of suspicious activity from those cheap accounts. It is generally listed as an Internet Bad Neighbourhood.
I'm sure that the same website will appear with another name and/or domain in a near future. The delivered product has the name of Formlife in it, so it is confirmed that this case is part of the long-running Danish/Swedish health product -scam.
Update (Sep 2013):
Finnish police publicly announced, that they won't investigate any foreign scams further, unless the damages exceed value of 5000 €. For the bad people, this is a license to keep on scamming. There is zero possibility of getting caught, because there won't be an international investigation.
In the above case the credit card company informed the victim that some money will be returned, if possible all of the lost money. Anyway, it will take months for the credit card company to process the issue.