...

суббота, 7 июня 2014 г.

Записываем видео из Google Street View

Некоторое время назад стала популярной тема Hyperlapse/time-lapse видео. В первую очередь, благодаря небезызвестному ресурсу http://ift.tt/14UpPFz



Сама по-себе возможность, конечно же замечательная, но сайт не позволяет сохранять результаты экспериментов в виде роликов. Вот эту досадную неприятность решено было исправить, и не просто исправить, а реализовать в виде программки для iOS, помогая тем самым, превратить iPhone или iPad в устройство для создания, а не потребления, контента.

Как всё устроено

Итак, на сегодняшний день у нас есть несколько ресурсов, позволяющих снимать Стрит Видео. В первую очередь, это, hyperlapse.tllabs.io/, который позволяет отметить 2 точки, пролодить меежду ними маршрут и наслаждаться зацикленной анимацией.

image

Второй сайт, который позволяет смотреть стрит видео это http://track-kit.net

image

Этот сайт позволяет просматривать видео для созданных или импорированных треков. Несмотря на то, что Стрит Видео здесь не является основной функцией, можно сгенерировать прямую ссылку именно на видео для тека. Например, такую:

http://ift.tt/1q5vCA8

Правда на моём Маке более-менее работает только в Хроме

Тем не менее, ни один из этих ресурсов не позволяет сохранять видео. Эту проблему мы сейчас и будем решать.

Для подготовки видео нам необходимо решить несколько задач.



  1. Проложить маршрут от точки А к точке Б. Желательно, отобразить доступность Гугл Стрит Вью.

  2. Загрузить кадры панорам

  3. Дать возможность пользователю отредактировать панорамы, например, направив камеру на какой-лиобо объект.

  4. Сгенерировать видео из набора кадров

  5. Решить ряд типичных для iOS проблемм.


Прокладываем маршрут



Для этого мы используем Google Maps SDK for iOS и Google direction API

С помощью Google direction API запрашиваем у Google набор точек между начальной и конечно точек пути в закодированном виде.

Google Maps SDK for iOS (класс GMSPath) понадобится чтобы перевести закодированый список точек который получили от Google в широту и долготу.

Для общения с Google используется AFNetworking.

static NSString *kLWSDirectionsURL = @"http://ift.tt/1exuaot?";
- (void)loadDirectionsForWaypoints:(NSArray *)waypoints{
NSString *origin = [waypoints objectAtIndex:0];
int waypointCount = [waypoints count];
int destinationPos = waypointCount -1;
NSString *destination = [waypoints objectAtIndex:destinationPos];
NSString *sensor = @"false";
NSMutableString *url = [NSMutableString stringWithFormat:@"%@&origin=%@&destination=%@&sensor=%@",
kLWSDirectionsURL,origin,destination, sensor];
if(waypointCount>2) {
[url appendString:@"&waypoints=optimize:true"];
int wpCount = waypointCount-2;
for(int i=1;i<wpCount;i++){
[url appendString: @"|"];
[url appendString:[waypoints objectAtIndex:i]];
}
}
url = [NSMutableString stringWithString:[url stringByAddingPercentEscapesUsingEncoding: NSASCIIStringEncoding]];
_directionsURL = [NSURL URLWithString:url];
[self startDownloadDataForURL:_directionsURL];
}

AFHTTPRequestOperation *requestOperation;
NSMutableArray* coordinatesArr;
-(void)startDownloadDataForURL:(NSURL*)url{
[self stopLoadingForUserInfo:userInfo];
requestOperation = [manager GET:[url absoluteString] parameters:nil success:^(AFHTTPRequestOperation *operation, id responseObject) {
NSString* status = [responseObject objectForKey:@"status"];
NSArray* routesArr = [responseObject objectForKey:@"routes"];
if ([status isEqualToString:@"OK"] && [routesArr count] > 0) {
NSDictionary *routes = [responseObject objectForKey:@"routes"][0];
NSDictionary *route = [routes objectForKey:@"overview_polyline"];
NSString *overview_route = [route objectForKey:@"points"];
GMSPath *path = [GMSPath pathFromEncodedPath:overview_route];

coordinatesArr = [NSMutableArray array];
for (int i = 0; i < [path count]; ++i) {
CLLocationCoordinate2D coord = [path coordinateAtIndex:i];
[coordinatesArr addObject:[NSValue valueWithMKCoordinate:coord]];
}
}
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
}];
}




Если загрузка прошла успешно в списке coordinatesArr мы храним набор координат точек нашего пути.

P.S. у Google direction API есть 1 нюанс — если необходимо провести маршрут не через 2, а скажем, через 20 точек, то придется делать несколько запросов для интервалов точек пути так как если передать в запрос через «&waypoints» большое количество промежуточных точек, Google может вернуть ошибку.
Загружаем панорамы



Для загрузки панорамы можно использовать запрос вида http://ift.tt/1pPvzeh,longitude

Он нам вернет информацию о ближайшей к точке панораме с координатами latitude,longitude.

Самое важное что мы можем получить это «panoId» — id нужной нам панорамы (помимо panoID мы можем получить так же информацию об углах смещения панорамы, которые могут пригодиться если надо будет повернуть панораму в определенном направлении):

NSString* panoID;

-(void)loadMyWebViewForCoord:(CLLocationCoordinate2D)arg{
@try {
if (!manager) {
manager = [AFHTTPRequestOperationManager manager];
}

NSString* urlStr = [NSString stringWithFormat:@"http://ift.tt/1uyX2AP",arg.latitude,arg.longitude];
request = [manager GET:urlStr parameters:nil success:^(AFHTTPRequestOperation *operation, id responseObject) {
id location = [responseObject objectForKey:@"Location"];
id projection = [responseObject objectForKey:@"Projection"];
if (location && projection) {
panoID = [location objectForKey:@«panoId»];
}
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
}];
}




Далее с помощью полученного ID панорамы мы можем через запрос:

http://ift.tt/1pPvwz9

получить уже необходимые нам тайлы панорамы, где panoId — это полученный ранее идентификатор панорамы, zoom — это масштаб панорамы (ее размер), x и y — это номера тайла панорамы по вертикали и горизонтали, при этом количество тайлов панорамы зависит от введенного нами зума. Например, если мы выберем zoom = 3, то панорама будет состоять из 7 тайлов в ширину и 3 в высоту.

То есть чтобы получить целую панораму нам надо загрузить все тайлы:

-(void)loadImagesForPanoPoint:(PanoPoint*)currentPanoPointArg {
@try {
int zoom;
int maxX;
int maxY;
if ([StreetViewSettings instance].hiQualityPano) {
zoom = 3;
maxX = 7;
maxY = 3;
}
else {
zoom = 2;
maxX = 4;
maxY = 2;
}
__block int allImages = maxX;
for (int x = 0; x < maxX; ++x) {
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^{
NSMutableArray* imForCurrentCoodY = [NSMutableArray array];
for (int y = 0; y < maxY; ++y) {
@autoreleasepool {
NSString* pathStr = [NSString stringWithFormat:@"http://ift.tt/1uyX2AV",currentPanoPointArg.panoID,zoom,x,y];
NSString* tempDirectory = NSTemporaryDirectory();
NSString* imPath = [NSString stringWithFormat:@"%@/panoLoadCash/%@zoom=%dx=%dy=%d_%d",tempDirectory,currentPanoPointArg.panoID,zoom,x,y,currentCoordArrIndex];
NSData* im = nil;
NSFileManager* fM = [NSFileManager defaultManager];
BOOL isD;
if (![fM fileExistsAtPath:imPath isDirectory:&isD]) {
im = [self imgByPath:pathStr];
}
else {
[imForCurrentCoodY addObject:imPath];
}
if (im) {
pakSize += im.length;
if (![fM fileExistsAtPath:[NSTemporaryDirectory() stringByAppendingString:@"panoLoadCash"] isDirectory:&isD]) {
NSError* err;
[fM createDirectoryAtPath:[NSTemporaryDirectory() stringByAppendingString:@"panoLoadCash"] withIntermediateDirectories:YES attributes:[NSDictionary dictionary] error:&err];
}
[im writeToFile:imPath atomically:YES];

[imForCurrentCoodY addObject:imPath];
}
}
}
[imForCurrentCoordV addObject:@(x)];
[imForCurrentCoordTemp addObject:imForCurrentCoodY];
--allImages;
});
}
}




Таким образом, пройдясь по всем точкам полученного от Google маршрута, мы можем загрузить для них панорамы и далее отобразить их пользователю в виде видео.
Генерируем видео



Для этого нам понадобится библиотека AVFoundation:

#import <AVFoundation/AVFoundation.h>




От туда берем всего 3 класса:

AVAssetWriter — запись медиа данных в файл

AVAssetWriterInput — Добавляет пакет медиаданных в AVAssetWriter для записи в файл

AVAssetWriterInputPixelBufferAdaptor — предоставляет пакет видеоданных (CVPixelBuffer) для AVAssetWriterInput

Соответственно нам надо их где-то определить:

AVAssetWriter* videoWriter;
AVAssetWriterInput* writerInput;
AVAssetWriterInputPixelBufferAdaptor* adaptor;




Далее инициализация:

NSError *error = nil;
videoWriter = [[AVAssetWriter alloc] initWithURL:[NSURL fileURLWithPath:videoPath]
fileType:AVFileTypeQuickTimeMovie
error:&error];

NSDictionary *videoSettings = [[NSDictionary alloc] initWithObjectsAndKeys:
AVVideoCodecH264, AVVideoCodecKey,
[NSNumber numberWithInt:videoSize.width], AVVideoWidthKey,
[NSNumber numberWithInt:videoSize.height], AVVideoHeightKey,
nil];

writerInput = [AVAssetWriterInput assetWriterInputWithMediaType:AVMediaTypeVideo outputSettings:videoSettings];

adaptor = [AVAssetWriterInputPixelBufferAdaptor assetWriterInputPixelBufferAdaptorWithAssetWriterInput:writerInput sourcePixelBufferAttributes:nil];

[videoWriter addInput:writerInput];
[videoWriter startWriting];
[videoWriter startSessionAtSourceTime:kCMTimeZero]




После этого все готово к записи видео.

В AVAssetWriterInput имеется функция:

(void)requestMediaDataWhenReadyOnQueue:(dispatch_queue_t)queue usingBlock:(void (^)(void))block

Которая, вызывает Block каждый раз когда нужна новая порция данных.

[writerInput requestMediaDataWhenReadyOnQueue:assetWriterQueue usingBlock:^
if (buffer == NULL)
{
CVPixelBufferPoolCreatePixelBuffer (NULL, adaptor.pixelBufferPool, &buffer);
}
UIImage *image = [self imageForIndex:currentIndexForBuff];

if (image) {
buffer = [self pixelBufferFromCGImage:image.CGImage];

CMTime presentationTime= CMTimeMakeWithSeconds(speed*currentIndexForBuff, 33);
if (![adaptor appendPixelBuffer:buffer withPresentationTime:presentationTime]) {
[self finishVideo];
return;
}
CVPixelBufferRelease(buffer);
if (currentIndexForBuff < imagesPathsForVideo.count) {
}
else {
[self finishVideo];
}
}
else {
if (currentIndexForBuff < imagesPathsForVideo.count) {
}
else {
[self finishVideo];
}
return;
}
++currentIndexForBuff;
}];




Скорость проигрывания видео контролируется с помощью переменной presentationTime, которая указывает время кадра в выходном файле

UIImage *image — это текущий кадр

Когда все кадры записаны в видео, мы сообщаем videoWriter и writerInput о том что необходимо остановить запись видео:

-(void)finishVideo {
[writerInput markAsFinished];
[videoWriter finishWritingWithCompletionHandler:^(){}];
}




Функция получения CVPixelBufferRef с изображения:

- (CVPixelBufferRef) pixelBufferFromCGImage: (CGImageRef) image
{
if (image) {
NSDictionary *options = [[NSDictionary alloc] initWithObjectsAndKeys:
[NSNumber numberWithBool:YES], kCVPixelBufferCGImageCompatibilityKey,
[NSNumber numberWithBool:YES], kCVPixelBufferCGBitmapContextCompatibilityKey,
nil];

CVPixelBufferRef pxbuffer = NULL;
CVPixelBufferCreate(kCFAllocatorDefault, CGImageGetWidth(image),
CGImageGetHeight(image), kCVPixelFormatType_32ARGB, (__bridge CFDictionaryRef) options,
&pxbuffer);

CVPixelBufferLockBaseAddress(pxbuffer, 0);
void *pxdata = CVPixelBufferGetBaseAddress(pxbuffer);

CGColorSpaceRef rgbColorSpace = CGColorSpaceCreateDeviceRGB();
CGContextRef context = CGBitmapContextCreate(pxdata, CGImageGetWidth(image), CGImageGetHeight(image), 8, 4*CGImageGetWidth(image), rgbColorSpace, kCGImageAlphaNoneSkipFirst);

CGContextDrawImage(context, CGRectMake(0, 0, CGImageGetWidth(image), CGImageGetHeight(image)), image);
CGColorSpaceRelease(rgbColorSpace);
CGContextRelease(context);

CVPixelBufferUnlockBaseAddress(pxbuffer, 0);

return pxbuffer;
}
else {
return nil;
}
}


Работа в фоновом режиме



Чтобы видео продолжало генерироваться когда наше приложение находится в фоновом режиме, можно использовать long-running background task для этого советую использовать неплохой класс

http://ift.tt/1q5vDny

Добавляя немножко опций, получаем такой вот программный продукт.

http://ift.tt/1q5vDnC

image

Вот пример видео, созданного при помощи такой программы:



Одним из интересных применений стрит видео был ныне покойный сайт 360° Langstrasse. От которого осталость только видео:





При помощи этой технологии можно создавать интересные проекты дополненной реальности, провдить географические изыскания и, конечно же. Развлекаться. На последок, немножко профессионального Time-lapse от Gunther Wegner


http://ift.tt/OYhsCG


This entry passed through the Full-Text RSS service — if this is your content and you're reading it on someone else's site, please read the FAQ at http://ift.tt/jcXqJW.


Как IPv6 помогает роутеры ломать

image

Предисловие




Проснулся я сегодня с мыслью, что огромное количество инструкций по настройке NAT советуют использовать строку вида:

iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE



Многие понимают проблемы этой конструкции, и советуют добавлять:

iptables -A FORWARD -i ppp0 -o eth1 -m state --state ESTABLISHED,RELATED -j ACCEPT



Но, зачастую, забывают задать таблице FORWARD действие REJECT по умолчанию, или добавить правило REJECT в конец таблицы.

На первый взгляд, вроде бы, все кажется нормальным. Однако, это далеко не так. Дело в том, что если не запретить маршрутизировать трафик из WAN-порта в WAN-порт, кто-нибудь из вашей WAN-сети (предположим, что провайдер садит весь подъезд в одну /24) может маршрутизировать трафик через вас, просто прописав ваш IP в качестве шлюза. Все современные SOHO роутеры это учитывают, а вот неопытный администратор, который делает роутер под обычным linux, может не знать или забыть об этом. В подсети моего провайдера таких роутеров не оказалось, и мой план по захвату мира провалился. Однако, статья совсем не об этом.

Магические двоеточия




Как вы, может быть, знаете, многие современные программы и сервисы биндятся на IP :: (два двоеточия), а не на 0.0.0.0, как было раньше. IPv6 адрес :: значит то же самое, что и IPv4 0.0.0.0, т.е. «слушаем все интерфейсы». Многие считают, что если программа слушает ::, то этот сокет может принимать только IPv6-соединения, однако это далеко не так.

В IPv6 есть так называемое отображение IPv4-адресов в IPv6 диапазон. Если программа слушает сокет ::, а к ней обращаются из IPv4-адреса 1.2.3.4, то программа получит соединение с адреса ::ffff:1.2.3.4. Этого можно избежать, сделав:

sysctl -w net.ipv6.bindv6only=1



Но это нужно далеко не всегда, т.к. обычно удобно, что программа слушает один сокет, а получать соединения может по двум протоколам сразу. Практически во всех дистрибутивах, IPv6-сокеты ведут себя именно так, т.е. bindv6only=0.

ff80 и его друг ff02




Если вы не застряли в 90-х, вы гарантированно сталкивались с IPv6, сами того не зная. Абсолютно во всех современных операционных системах по умолчанию включена поддержка IPv6, а это значит, что на каждый (кроме редких исключений) интерфейс автоматически назначается IPv6 Link-Local адрес, который начинается с ff80::. Более того, в некоторых случаях этот адрес получается просто путем кодирования MAC-адреса.

Казалось бы, найти Link-Local адреса должно быть проблематично, они же все-таки длинные и страшные, но тут нам на помощь приходит мультикаст-диапазон ff02::.

Есть такой классный адрес: ff02::1. Если его попинговать (обязательно с указанием интерфейса, т.к. это Link Local адрес), то откликнутся все компьютеры в сети:



% ping6 ff02::1%enp4s0
PING ff02::1%enp4s0(ff02::1) 56 data bytes
64 bytes from fe80::21f:d0ff:fea2:46a3: icmp_seq=1 ttl=64 time=0.056 ms
64 bytes from fe80::fe8b:97ff:fe66:9100: icmp_seq=1 ttl=64 time=1.60 ms (DUP!)
64 bytes from fe80::226:9eff:fe6d:22a0: icmp_seq=1 ttl=64 time=1.62 ms (DUP!)
64 bytes from fe80::f2de:f1ff:fe27:3685: icmp_seq=1 ttl=64 time=1.70 ms (DUP!)
64 bytes from fe80::62a4:4cff:fe7b:1c90: icmp_seq=1 ttl=64 time=2.95 ms (DUP!)
64 bytes from fe80::fac0:91ff:fe32:5bbe: icmp_seq=1 ttl=64 time=3.02 ms (DUP!)
64 bytes from fe80::226:18ff:fe9e:4b3a: icmp_seq=1 ttl=64 time=3.09 ms (DUP!)
64 bytes from fe80::ba70:f4ff:fe8b:8dda: icmp_seq=1 ttl=64 time=3.14 ms (DUP!)
64 bytes from fe80::62a4:4cff:fea2:aee0: icmp_seq=1 ttl=64 time=3.27 ms (DUP!)
64 bytes from fe80::224:54ff:fedb:d17d: icmp_seq=1 ttl=64 time=3.93 ms (DUP!)
64 bytes from fe80::2a1:b0ff:fe40:904: icmp_seq=1 ttl=64 time=4.21 ms (DUP!)
64 bytes from fe80::76d0:2bff:fe69:31d8: icmp_seq=1 ttl=64 time=6.09 ms (DUP!)




Как мы видим, откликнулось 11 устройств. Кстати, этот адрес очень удобно использовать, если у вас, например, сервер настроен на получение адреса через DHCP, а DHCP упал, или если вы напрямую подключились к порту сервера, а DHCP поднимать не хочется. Вам остается просто зайти по fe80-адресу по ssh.

Если попинговать адрес ff02::2, то откликнутся все IPv6-роутеры в сети. К сожалению, в моем случае таких не было.


Сканируем роутеры




Я решил просканировать эти адреса через nmap, и вот что вышло:

% nmap -6 -T4 --open -n -iL list.txt

Скрытый текст


Starting Nmap 6.46 ( http://nmap.org ) at 2014-06-07 16:53 MSK
Nmap scan report for fe80::f2de:f1ff:fe27:3685
Host is up (0.0014s latency).
Not shown: 999 closed ports
PORT STATE SERVICE
53/tcp open domain

Nmap scan report for fe80::fe8b:97ff:fe66:9100
Host is up (0.0012s latency).
Not shown: 998 closed ports
PORT STATE SERVICE
53/tcp open domain
80/tcp open http

Nmap scan report for fe80::226:9eff:fe6d:22a0
Host is up (0.0012s latency).
Not shown: 998 closed ports
PORT STATE SERVICE
53/tcp open domain
80/tcp open http

Nmap scan report for fe80::62a4:4cff:fea2:aee0
Host is up (0.00099s latency).
Not shown: 999 closed ports
PORT STATE SERVICE
23/tcp open telnet

Nmap scan report for fe80::226:18ff:fe9e:4b3a
Host is up (0.00094s latency).
Not shown: 999 closed ports
PORT STATE SERVICE
23/tcp open telnet

Nmap scan report for fe80::62a4:4cff:fe7b:1c90
Host is up (0.00085s latency).
Not shown: 999 closed ports
PORT STATE SERVICE
23/tcp open telnet

Nmap scan report for fe80::76d0:2bff:fe69:31d8
Host is up (0.00072s latency).
Not shown: 999 closed ports
PORT STATE SERVICE
23/tcp open telnet

Nmap scan report for fe80::fac0:91ff:fe32:5bbe
Host is up (0.00037s latency).
Not shown: 999 closed ports
PORT STATE SERVICE
23/tcp open telnet

Nmap scan report for fe80::ba70:f4ff:fe8b:8dda
Host is up (0.00059s latency).
Not shown: 999 closed ports
PORT STATE SERVICE
23/tcp open telnet

Nmap scan report for fe80::2a1:b0ff:fe40:904
Host is up (0.00077s latency).
Not shown: 999 closed ports
PORT STATE SERVICE
23/tcp open telnet

Nmap scan report for fe80::224:54ff:fedb:d17d
Host is up (0.0012s latency).
Not shown: 999 closed ports
PORT STATE SERVICE
23/tcp open telnet

Nmap done: 11 IP addresses (11 hosts up) scanned in 4.04 seconds





По IPv4 все эти порты закрыты.

Как мы видим, у многих роутеров открыт Telnet, веб-интерфейс и DNS извне по IPv6.

Что же это значит? Все просто — разработчики прошивки роутера просто-напросто забыли про IPv6.

Роутеры с открытым telnet:



  • ASUS RT-N10 (2.0.3.2)

  • ASUS RT-G32

  • ASUS RT-G32.C1 (2.0.2.6)

  • Upvel UR-312N4G




Роутеры с открытым веб-интерфейсом:


  • D-Link DIR-615 (E4, 5.11NV)

  • D-Link DIR-615 (E4, 5.11RU)


На многих из них были стандартные пароли admin/admin.

На большинстве этих роутеров ip6tables (iptables для IPv6) просто отсутствовал. Разработчики должны были либо вообще отключить поддержку IPv6 в ядре, либо убедиться, что http и telnet демоны слушают 0.0.0.0, а не :: но, по какой-то причине не стали этого делать.


А что, если…?




Если бы на роутере был каким-то образом настроен IPv6, и, соответственно, включена маршрутизация IPv6 пакетов (net.ipv6.conf.all.forwarding=1), а ip6tables либо вообще не настроен, либо настроен неправильно, то можно было бы точно так же, как в случае с IPv6, маршрутизировать пакеты через этот роутер, а учитывая отображение IPv4-адресов в IPv6, можно было бы маршрутизировать и IPv4 пакеты через Link-Local IPv6 адрес.

Заключение




Некоторым компаниям я уже отправил письма об этих уязвимостях, а некоторым еще не успел. В любом случае, письма будут отправлены всем.

Используйте IPv6, не забывайте о нем.

P.S.




Для меня стало неожиданностью, что браузеры не умеют открывать адреса с указанием интерфейса. У меня никак не получилось открыть ссылку вида http://[fe80::a:b:c:d%enp4s0] во всех браузерах. Говорят, что знак процента нужно экранировать, т.е. http://[fe80::a:b:c:d%25enp4s0], но у меня и так не вышло. Пришлось использовать проброс портов.

This entry passed through the Full-Text RSS service — if this is your content and you're reading it on someone else's site, please read the FAQ at http://ift.tt/jcXqJW.


Как разрабатывать безопасные приложения под Android. Семинар в Яндексе

Доля пользователей, которые применяют в ежедневной жизни мобильные устройства, неуклонно возрастает. Большая часть этих устройств – смартфоны и планшеты на базе iOS, Android и Windows. Мобильность, специфические особенности взаимодействия пользователя с устройством и новые операционные системы – факторы, приводящие к появлению необычных проблем, связанных с информационной безопасностью. Мы рассмотрим часть из этих проблем, их решения, и на практике убедимся, что разработка инструментов для анализа мобильных приложений не так уж сложна.

Начнем с того, что перечислим несколько характерных для большинства мобильных устройств черт, которые могут влиять в том числе и на безопасность:



  • миниатюрность;

  • массовость;

  • универсальность;

  • хранение важных для пользователя данных;

  • постоянное подключение к сети (GPRS/3G/EDGE/WiFi).




Так какие же риски порождают эти особенности. Миниатюрность приводит к тому, что устройство нетрудно потерять, после чего оно потенциально может оказаться в руках злоумышленника. Массовость и простота монетизации делает устройства привлекательными для злоумышленников. Просто заставив телефон послать SMS на платный номер, можно получить неплохую выгоду. Большое количество пользователей также означает, что и процент не очень технически грамотных пользователей достаточно велик. Универсальность мобильных устройств подразумевает, что в них может храниться практически весь спектр персональной информации, которую можно использовать: контакты, переписка, фотографии, видео, пароли и токены от различных важных сервисов вплоть до банковских клиентов. Постоянное подключение к сети – это дополнительный риск, так как злоумышленникам не нужно выгадывать моменты для атаки.



К сожалению, из-за того, что рынок мобильных устройств пережил такой взрывной рост, безопасники немного поотстали от противостоящей стороны, поэтому сейчас между ними и злоумышленниками идут практически гонки на выживание. Это непросто. Устройства производят десятки различных вендоров, они работают под управлением разных платформ, на них устанавливаются огромное количество приложений, во многих из которых есть уязвимости. Все это порождает огромное количество проблем.

Безопасность в Android




Конечно, разработчики мобильных платформ знают обо всех этих рисках и стараются предусмотреть защиту от них. Рассмотрим, какие уровни защиты есть в Android. Во-первых, там есть защита от физического доступа: PIN, пароли, биометрия, росчерки. Однако биометрия там весьма специфическая, а с паролями и росчерками есть определенные проблемы: при вводе на экране могут оставаться заметные следы, по которым можно восстановить, что именно было набрано.


Тем не менее, защита есть, и часто срабатывает. Для приложений также есть несколько уровней защиты. Во-первых, у почти всегда у приложений есть уникальные UID и запускаются они отдельными процессами и в изолированной виртуальной машине. Интересная особенность Android – нединамические привилегии приложений: все доступы запрашиваются при установке. Т.е. пользователь сразу ознакомлен с тем, к чему могут обращаться приложения. К вопросу безопасности файловой системы разработчики Android подошли достаточно строго. Системный раздел примонтирован в режиме read-only, расстановка привилегий и прав в файловых системах сделана практически вручную, начиная с версии 3.0 появилось шифрование файловой системы. Приведу пример скрипта init.rc для андроидов версий 4.x:



...
# create data/gps for GPS demon
mkdir /data/gps 771 gps system
chown gps system /data/gps
chown gps root /sys/class/sec/gps/GPS_PWR_EN/value
chmod 660 /sys/class/sec/gps/GPS_PWR_EN/value

# for sensor control
chown system input /sys/class/input/input0/enable
chown system input /sys/class/input/input0/delay
chown system input /sys/class/input/input0/wake
chown system input /sys/class/input/input0/data
...


Это лишь небольшая часть скрипта, но видно, что права на файлы и папки для критически важных участков системы расставляются очень тщательно. Доступа к ним у злоумышленника быть не должно.


Разработчики также позаботились о возможности шифрования трафика, внедрив SSL. Однако тут есть одна специфическая особенность. В Android есть хранилище корневых сертификатов, и если заглянуть в дамп этого хранилища, то можно обнаружить, интересную штуку: кроме корневых сертификатов известных удостоверяющих центров, там есть и довольно странные сертификаты. Например, сертификат японского правительства:



...

Alias name: 123
Creation date: 30.08.2011
Entry type: trustedCertEntry

Owner: C=JP,O=Japanese Government,OU=ApplicationCA
Issuer: C=JP,O=Japanese Government,OU=ApplicationCA
Serial number: 31
Valid from: Wed Dec 12 18:00:00 MSK 2007 until: Tue Dec
12 19:00:00 MSK 2017

...


Такой же сертификат есть и от правительства Китая. Так что, находясь в Японии или Китае, вы можете стать жертвой атаки типа man in the middle. По счастью, в четвертых андроидах встроенное хранилище можно отключить.


Как я уже говорил выше, механизм привилегий в Android достаточно хитроумный. Разработчики изначально выделили API-вызовы, которые могут предоставлять определенные риски и разделили на группы: доступ к камере, bluetooth, геолокации, сообщениям, звонкам, сети. Чтобы воспользоваться этими API приложение должно при установке в явном виде запросить к ним доступ. Механизм гибкий и удобный, но не лишенный некоторых проблем, с которыми иногда сталкиваются разработчики. Дело в том, что механизм этот не очень хорошо документирован, буквально несколько строчек описывают каждое разрешение. И разработчики очень часто сталкиваются с тем, что создаваемое приложение не работает из-за недостатка разрешений. Многие не разбираются, а просто запрашивают как можно больше разрешений. Все начинает работать, но при этом приложение имеет доступ к совершенно ненужным вещам, что крайне отрицательно влияет на безопасность. Компания Google, понимая эту проблему, выделила грант сторонним исследователям на более подробное описание API.


Пользователи и Android




Итак, мы пришли к выводу, что операционная система все-таки относительно защищена. В чем же может быть проблема? Часто проблемы возникают по вине самих пользователей. Есть множество способов сломать защиту системы самостоятельно, без вмешательства злоумышленников. Первый способ – jailbreaking. На андроиде он делается на удивление легко. Часто можно просто в загрузчике выбрать, что загружать вместо обычного ядра операционной системы. Это позволяет полностью убить практически все защитные механизмы. Часто пользователи используют слишком простые пароли, которые без труда взламываются злоумышленниками. Иногда пользователи ставят странные приложения из недоверенных источников. В принципе, троянского коня можно заполучить даже в Google Play, но при установке из сторонних магазинов или с пиратских сайтов вероятность такого исхода возрастает в разы. Часто пользователи забывают отключать на устройстве режим отладки, который позволяет не только быстро установить jailbreak, но и быстро вытащить все данные, получив физический доступ к устройству. Впрочем, в современных версиях Android уже меньше проблем с отладочным режимом.

Разработчики и Android




К сожалению, проблемы возникают не только по вине пользователей. Причиной могут стать и разработчики. В первую очередь проблемы возникают, когда разработчики не до конца понимают, как их приложение функционирует на мобильной платформе. Очень часто можно видеть такое ограниченное мировоззрение, когда разработчик представляет себе некоторое абстрактное устройство, на котором в вакууме работает его сферическое приложение, с которым взаимодействует только пользователь. Это слишком однобокая картина. Например, она не учитывает, что к устройству может получить физический доступ злоумышленник. Значительная часть приложений взаимодействует с серверным бэкэндом, о безопасности которого многие забывают. Часто не принимается во внимание, что приложение может взаимодействовать с другими установленными программами, которые могут оказаться вредоносными. Да и с устройством приложения взаимодействуют не напрямую, а через фреймворки, среду исполнения, библиотеки, ОС. В каждом из этих компонентов могут быть уязвимости. И уязвимости эти могут быть очень низкоуровневыми: в ядре, в драйверах, в оболочках вендоров.

В приложениях также могут возникать проблемы. Многие разработчики позволяют своим приложениям хранить данные не только в своем изолированном участке файловой системы, но и в общедоступном хранилище (например, на SD-карте). Позволяя сохранять таким образом конфиденциальные пользовательские данные, разработчик создает серьезную уязвимость. Еще одна потенциальная приманка для злоумышленников – передача данных по открытым каналам, либо через SSL, но без проверки сертификатов. Для мобильных устройств также актуален практически весь набор уязвимостей их больших братьев. Многие об этом забывают и не обеспечивают санитизацию пользовательского ввода. Используя для отображения информации WebView, также можно получить весь букет атак. Специфичная для андроида проблема – передача чувствительных данных в лог-файлы. Пользователи часто не обращают внимание на запрос чтения системных лог-файлов со стороны приложения. А разработчики часто забывают в релизных версиях минимизировать отладочную информацию, попадающую в логи. Из-за этого туда может записываться очень важная информация. Например, токены, которыми могут воспользоваться злоумышленники.


Работа приложения в сэндбоксе – не панацея против атак. Работать в полной изоляции приложение не может, у него должны быть точки взаимодействия, как с другими приложениями, так и с операционной системой. Межпроцессное взаимодействие в андроиде достаточно гибкое. Например, ваше приложение может содержать в себе такую функциональность, как контент-провайдеры, позволяющую сторонним приложениям получить доступ к данным. Существуют также сервисы, активности и бродкаст ресиверы, которые могут получать доступ к сообщениям, циркулирующим внутри операционной системы. Фактически, если эти компоненты не защищены привилегиями, как это часто бывает, к ним может обратиться какой-то сторонний код. В итоге некоторое приложение может производить действия, которые ему доступны быть не должны. Допустим, ваше приложение имеет доступ к чтению и отправке SMS. Если вы забудете ограничить доступ к контент-провайдерам, кто угодно сможет прочитать сообщения пользователя, не обладая необходимыми привилегиями.


Анализ контент-провайдеров




Перейдем к практической части. Контент-провайдеры позволяют получить доступ к информации через универсальный интерфейс, это такая абстракция курсора баз данных. В качестве контент-провайдера доступна, например, адресная книга. Разрешения на доступ к ним могут быть не установлены ни на чтение, ни на запись, что позволяет злоумышленнику просмотреть или внести какую-то критичную информацию. Для выявления таких уязвимостей есть несколько программных средств. В качестве примеров я хотел бы упомянуть Mercury, разработку компании MWR, и свою standalone-утилиту CPA. Если задаться целью написать такое приложение самостоятельно, то можно понять следующее. Так как многие вещи регистрируются при установке приложения, данные о контент-провайдерах извлечь очень легко. Они прописываются в манифесте приложения, контент-провайдеры регистрируются, соответственно, информация о них доступна через стандартный менеджер пакетов андроида. Там содержатся сведения как о пути, по которому доступен контент-провайдер, так и о привилегиях. Соответственно, я своей утилитой эти данные извлекаю и даю возможность выбрать любой из контент-провайдеров. Естественно, интерес представляют именно незащищенные. Далее можно попытаться передать контент-провайдеру данные, либо заставить его прочитать какой-либо файл. Результаты можно получить довольно неожиданные. Например, на смартфонах Samsung Galaxy S есть биометрическая блокировка экрана, которая снимается, когда пользователь подносит камеру к своему лицу. Это приложение ставит вместе с собой контент-провайдер com.sec.provider.facekey.


Привилегий на чтение и запись у него нет. Если попытаться к этому провайдеру обратиться, используя запрос * from sqlite_master--, результат будет весьма неожиданным. Вернее, он будет неожиданным для тех, кто думает, что SQL-инъекции бывают только в веб-приложениях. Этот запрос позволяет ознакомиться со всей базой данных, дам действительно есть SQL-инъекция. И мы видим там забавную таблицу с названием facefeature, у которой есть поля «особенности лица» и «изображение лица». Можно обратиться к ним напрямую и получить закодированные данные. Таким образом, не имея никаких привилегий, мы получаем доступ к биометрическим данным пользователя.


Ближайший научно-технический семинар в Яндексе состоится 10 июня. Он будет посвящен теме рекомендательных систем и распределенных алгоритмов .


This entry passed through the Full-Text RSS service — if this is your content and you're reading it on someone else's site, please read the FAQ at http://ift.tt/jcXqJW.


DevConf::Mobi — уже на следующей неделе 14 июня, сформирована программа секции

Добро пожаловать на уникальную конференцию сообществ разработчиков DevConf 2014,

которая пройдет 14 июня в Москве.

Секция Mobi — представлена следующими докладами:


Особенности использования и приемы оптимизации использования AZURE для PUSH нотификаций под все платформы.

Демьянов Артем — мобильный разработчик, Java Developer. Программирует на Java более 5 лет. Под Android более 3-х лет. Сегодня является лидером команды и контроллирует разработку детских мобильных приложений под все платформы. Детские мобильные приложения, разработанные Артемом висят в TOP 10 Google Play в разделе Образование. Выступал на Tabtabus, Droidcon и многих других конференциях.


Методология построения мобильных push бекэндов

Александр Михайленко, со-основатель мобильной платформы Jeapie, попавшей в топ10 самых перспективных стартапов Украины 2014.


Программирование под Android на языке Kotlin

Филипп Торчинский — эксперт по технологиям в компании JetBrains. Основная специализация — UNIX-технологии, основные интересы в данный момент — облачные технологии, системы отслеживания заявок, IDE.



Разработка приложений Tizen Wearable для Samsung Gear 2

Кирилл Данилов Старший специалист по руководству проектами мобильных платформ» в компании Samsung Electronics Russia, имеет большой опыт разработки мобильных приложений под разные платформы. Сторонник хакатон движения, открытых вэб технологий и мобильных решений.


Разработка NFC-приложений под Android

Михаил Дударев, работает с Java Security более 15 лет, основатель проекта jCardSim, Java Card симулятора, завоевавшего награду Duke's Choice Award 2013


Пиратство и другие угрозы для Android-приложений. Как защищаться?

Иван Кинаш — генеральный директор и со-основатель компании Licel. Более 10 лет опыта в самых разных областях IT.


Разработка под Android Wear

Андрей Басков, со-основатель и генеральный директор Touch Instinct


Не пропусти DevConf::Mobi! Регистрируйся сейчас!


This entry passed through the Full-Text RSS service — if this is your content and you're reading it on someone else's site, please read the FAQ at http://ift.tt/jcXqJW.


[Перевод] Выпущен рекордный долгострой ПО, создававшийся 54 года

image

Когда потребителям обещают новые мощные программы, которые изменят их жизнь, а затем начинаются задержки и отсрочки, ситуация не из приятных.


Так, Max OS X впервые была показана под кодовым названием Rhapsody в 1997 году, но выпуск первой версии состоялся только спустя четыре года. Выпуск Windows Vista планировался на 2003 год как второстепенное обновление между Windows XP и полноценной новой версией, но ждать пришлось целых три года.


Однако оба упомянутых примера – ничто в сравнении с проектом Xanadu, который в конце апреля был без лишней помпы представлен на мероприятии в калифорнийском Чемпенском университете. Разработка Xanadu началась 54 года назад – в 1960 году. Это самое долго разрабатываемое ПО в истории.


Именно разработчик Xanadu Тед Нельсон (Ted Nelson) придумал термин «гипертекст» для обозначения нажимаемых ссылок в своем проекте. Именно этот термин в виде сокращения «ht» стоит в аббревиатуре «http».


Если вкратце, Xanadu позволяет создавать документы, в которые внедрены источники, на которые эти документы ссылаются. По словам Нельсона, таким образом создается «целая форма литературы, в которой ссылки не разрушаются со сменой версий, документы можно выводить рядом друг с другом для сравнения или аннотаций и сразу видишь происхождение каждой цитаты, причем с полноценной системой защиты авторских прав. Это система для литературного, юридического и делового использования, которая обеспечивает беспроблемное и безоговорочное цитирование в любое время и в любом количестве».


В Интернете представлена версия под названием OpenXanadu. Это простой документ с цитатами из восьми источников, таких как Библия короля Якова и страница из Википедии о теории стационарной вселенной. Навигация осуществляется пробелом и курсорами, а инструкция предупреждает: не трогать мышь! Можно переходить между оригиналами и результирующим документом и обратно.


На первый взгляд, это похоже на веб, и неспроста. Одно время Xanadu вполне мог опередить Тима Бернерса-Ли, изобретателя всемирной паутины, она же веб. Но проект забуксовал, и веб пришел к финишу первым.Тед Нельсон


Упустив шанс изобрести веб, теперь Нельсон видит в Xanadu альтернативу форматам, которые пытаются быть похожими на бумагу, а не изобретать что-то новое для цифровой эпохи.


«В 1980-х годах мы оплошали, упустили шанс стать всемирным гипертекстом (эту нишу занял веб). Однако мы все еще можем конкурировать с PDF, который имитирует бумагу, путем демонстрации текстовых связей».


В 1995 году, когда разработка проекта длилась уже 35 лет, автор Wired Гэри Вулф (Gary Wolf) охарактеризовал Нельсона как человека, который никогда не умел воплощать в жизнь свои идеи, хотя сами по себе эти идеи были очень важными.


«Затруднения Нельсона породили одну из самых мощных разработок 20-го века, – писал тогда Вулф. – Цели Xanadu, такие как универсальная библиотека, глобальный информационный индекс и компьютеризированная система роялти, разделяли многие из умнейших программистов первого поколения хакеров».


This entry passed through the Full-Text RSS service — if this is your content and you're reading it on someone else's site, please read the FAQ at http://ift.tt/jcXqJW.


Samsung представляет новую серию SSD-накопителей 845DC EVO


сегодня в 14:10


Добрый день, Хабр!

Samsung представила новые твердотельные накопители Samsung 845DC EVO, предназначенные для использования в крупных дата-центрах и других серверных системах корпоративного класса, в том числе в среде малого и среднего бизнеса. Новинки несут в себе фирменную 3-битную NAND флэш-память 10-нм класса, встроенное программное обеспечение и контроллер, которые основаны на SSD Samsung PM853T.





845DC EVO доступны в опциях с 240 ГБ, 480 ГБ и 960 ГБ на борту. Новые SSD обеспечивают скорость последовательного чтения данных до 530 Мб/сек, а в режиме произвольного чтения скорость доходит до 87 000 IOPS. Помимо этого, Samsung предоставляет гарантию на накопители до 600 терабайт TBW (Total Bytes Written). Этот показатель надежности отображает тот объем данных, который можно записать на SSD до исчерпания ресурса ячеек памяти. Активное энергопотребление Samsung 845DC EVO составляет приблизительно 4 Вт — это всего лишь 25% от объема энергозатрат эквивалентных HDD для дата-центров.


Новые SSD станут доступны по всему миру в конце июня. Цены для отечественного рынка пока можно только прикинуть в уме, основываясь на анонсированных ценах для США: $250, $490 и $970 за версии с 240 ГБ, 480 ГБ и 960 ГБ соответственно.




Только зарегистрированные пользователи могут оставлять комментарии.

Войдите, пожалуйста.


This entry passed through the Full-Text RSS service — if this is your content and you're reading it on someone else's site, please read the FAQ at http://ift.tt/jcXqJW.


Делаем лазерный проектор из (почти) подручных материалов

Изначально я планировал сделать Лазерную арфу, но пока получился промежуточный результат — устройство, которое можно использовать как лазерный проектор — рисовать лазером различные фигуры, записанные в файлах формата ILDA. Я в курсе, что многие, кто берется за сборку лазерного проектора, в качестве устройства, управляющего гальванометрами (так и не понял как лучше перевести на русский сочетание “galvo scanner"), используют дешевые слегка модифицированные звуковые платы для компьютера. Я пошел иным путем, так как в конечном счете мне нужно будет полностью автономное устройство, которое может работать без компьютера.


Посмотрим из чего состоит мой лазерный проектор. Стоимость всех деталей составила около 8000 руб, из которых больше половины — это 70mW лазерный модуль.



  1. Гальванометры и драйверы к ним для отклонения луча лазера по осям X/Y

  2. 532нм 70mW лазерный модуль с питанием от 5В Dragon Lasers SGLM70

  3. Texas Instruments Stellaris Launchpad

  4. Самодельная плата с ЦАП AD7249BRZ

  5. Блок питания






Железо




В моей системе используется Stellaris Launchpad в качестве «мозга» (потому что он достаточно быстрый и имеет аппаратную поддержку USB) и 12-битный двухканальный ЦАП с последовательным интерфейсом Analog Devices AD7249BRZ. Для управления отклонением луча на вход драйвера нужно подавать аналоговый сигнал в диапазоне от -5 до 5 вольт. ЦАП AD7249BRZ как раз умеет работать в таком режиме (а также от 0 до 5 вольт и от 0 до 10 вольт). Для него я развел в Eagle специальную плату, которая подключается к Stellaris Launchpad. Плата требует двухполярного питания, которое получается с помощью микросхемы ICL7660. Для преобразования единственного выходного напряжения поставляемого с гальванометрами блока питания (15В) в нужные мне я использовал линейный регулятор LM317, что в последствии оказалось не самым оптимальным решением, особенно для питания лазерного модуля — потому что LM-ка с большим радиатором (виден на видео) через минут 10 работы нагревается градусов до 70. Без радиатора она просто очень быстро перегревалась и отключалась от перегрева (а вместе с ней и лазерный модуль, из-за чего я поначалу решил что он сгорел и чуть не отложил пару кирпичей, т.к. при повторной подаче питания он не включался — как уже потом выяснилось до тех пор, пока не остынет микросхема).

Лазерный модуль изначально не поддерживал TTL-модуляцию, поэтому когда мне надоело просто водить лазером в разные стороны я задумался о том, чтобы в нужные моменты времени включать и отключать луч. Для этого потребовалось дорабатывать лазерный модуль паяльником. К счастью, почти все китайские лазерные модули весьма похожи друг на друга, просты, и сделаны на операционном усилителе LM358. Подпаяв к его ногам 3 и 4 (неинвертирующий вход и земля соответственно) эмиттер и коллектор первого попавшегося биполярного транзистора 2N4401, я, таким образом, получил возможность модулировать работу лазера, подавая управляющий сигнал на базу транзистора:



Доработанный напильником лазерный модуль



Схема и плата для AD7249BRZ представлена ниже. Возможно внимательный читатель найдет в схеме ошибку, потому что в ней по неизвестным мне причинам кажется не работает часть с операционным усилителем, которая призвана сделать выходной сигнал схемы балансным для пущей защиты от помех. Мой экземпляр вместо балансного сигнала выдает небалансный, но, тем не менее, все работает и так.



Надеюсь вы не испугались страшной картинки платы с налетом у выводов микросхемы, который образовался после протирки этиловым спиртом. Кстати, по этой причине рекомендуют отмывать флюс изопропиловым спиртом, так как он не оставляет таких разводов. Кстати, кому интересно, что это за разъемы такие с защелкой на плате — это разъемы Molex (22-23-2021 розетка, 22-01-3027 вилка, 08-50-0114 контакт для вилки), заказывал их через Digikey, так как у китайцев они стоят как-то неприлично дорого.

Софт




На этом вроде все самое интересное про железную часть заканчивается, так что переходим к части софтовой. Состоит она из двух частей — программки для ПК и прошивки для Stellaris Launchpad, которая реализует USB bulk-устройство с собственным форматом пакетов по 32 бита в каждом. Формат сэмпла описан следующей структурой:

typedef struct
{
unsigned x:12; // координата X
unsigned rx:4; // флаг (вкл/выкл лазер)
unsigned y:12; // координата Y
unsigned ry:4; // не используется
} sample_t;




Устройство использует USB-буферы размером 512 байт, в которые с ПК с некоторым запасом, и с такой скоростью, чтобы не вызвать переполнение или опустошение буфера, записывает данные. Используемые гальванометры рассчитаны на отображение 20000 точек в секунду, то есть это требуемая частота семплирования. В функции обработки данных от USB скорость обработки регулируется с помощью банального SysCtlDelay. Регулируя значение можно подстроить систему, так чтобы тестовая картинка ILDA отображалась правильно:



Зеленый светодиод на видео в начале поста мигает после обработки каждой пачки в 20000 сэмплов. То есть, в идеале он должен мигать ровно 1 раз в секунду.

Программная часть для ПК основана на playilda.c из пакета OpenLase, однако оттуда вырезано все лишнее и вместо взаимодействия с сервером JACK используется libusb для отправки пакетов данных на Stellaris Launchpad.


Исходный код программы для ПК


#include <stdlib.h>
#include <sys/time.h>
#include <time.h>
#include <stdio.h>
#include <string.h>
#include <libusb-1.0/libusb.h>
#include <iostream>
#include <string>
#include <vector>

#define MAGIC 0x41444C49

static inline uint16_t swapshort(uint16_t v) {
return (v >> 8) | (v << 8);
}

float scale = 1.0;

typedef struct {
uint32_t magic;
uint8_t pad1[3];
uint8_t format;
char name[8];
char company[8];
uint16_t count;
uint16_t frameno;
uint16_t framecount;
uint8_t scanner;
uint8_t pad2;
} __attribute__((packed)) ilda_hdr;

#define BLANK 0x40
#define LAST 0x80

typedef struct {
int16_t x;
int16_t y;
int16_t z;
uint8_t state;
uint8_t color;
} __attribute__((packed)) icoord3d;

typedef struct coord3d {
int16_t x;
int16_t y;
int16_t z;
uint8_t state;

coord3d(int16_t x, int16_t y, int16_t z, uint8_t state) : x(x), y(y), z(z), state(state) { }
} coord3d;

typedef struct {
std::vector<coord3d> points;
int position;
} frame;

frame rframe;
int subpos;
int divider = 1;

int loadildahdr(FILE *ild, ilda_hdr & hdr)
{
if (fread(&hdr, sizeof(hdr), 1, ild) != 1) {
std::cerr << "Error while reading header" << std::endl;
return -1;
}

if (hdr.magic != MAGIC) {
std::cerr << "Invalid magic" << std::endl;
return -1;
}

if (hdr.format != 0) {
fprintf(stderr, "Unsupported section type %d\n", hdr.format);
return -1;
}

hdr.count = swapshort(hdr.count);
hdr.frameno = swapshort(hdr.frameno);
hdr.framecount = swapshort(hdr.framecount);
}

int loadild(const std::string & file, frame & frame)
{
int i;
FILE *ild = fopen(file.c_str(), "rb");

if (!ild) {
std::cerr << "Cannot open " << file << std::endl;
return -1;
}

ilda_hdr hdr;
loadildahdr(ild, hdr);

for (int f = 0; f < hdr.framecount; f++)
{
std::cout << "Frame " << hdr.frameno << " of " << hdr.framecount << " " << hdr.count << " points" << std::endl;
icoord3d *tmp = (icoord3d*)calloc(hdr.count, sizeof(icoord3d));

if (fread(tmp, sizeof(icoord3d), hdr.count, ild) != hdr.count) {
std::cerr << "Error while reading frame" << std::endl;
return -1;
}

for(i = 0; i < hdr.count; i++) {
coord3d point(swapshort(tmp[i].x), swapshort(tmp[i].y), swapshort(tmp[i].z), tmp[i].state);
frame.points.push_back(point);
}

free(tmp);

loadildahdr(ild, hdr);
}

fclose(ild);
return 0;
}

short outBuffer[128];

int process()
{
frame *frame = &rframe;

short *sx = &outBuffer[0];
short *sy = &outBuffer[1];

for (int frm = 0; frm < 64; frm++) {
struct coord3d *c = &frame->points[frame->position];

*sx = 4095 - (2047 + (2048 * c->x / 32768)) * scale;
*sy = (2047 + (2048 * c->y / 32768)) * scale;

if(c->state & BLANK) {
*sx |= 1 << 15;
} else {
*sx &= ~(1 << 15);
}

sx += 2;
sy += 2;

subpos++;
if (subpos == divider) {
subpos = 0;
if (c->state & LAST)
frame->position = 0;
else
frame->position = (frame->position + 1) % frame->points.size();
}
}

return 0;
}

int main(int argc, char **argv)
{
libusb_device_handle *dev;
libusb_context *ctx = NULL;
int ret, actual;

ret = libusb_init(&ctx);
if(ret < 0) {
fprintf(stderr,"Couldn't initialize libusb\n");
return EXIT_FAILURE;
}

libusb_set_debug(ctx, 3);

dev = libusb_open_device_with_vid_pid(ctx, 0x1cbe, 0x0003);
if(dev == NULL) {
fprintf(stderr, "Cannot open device\n");
return EXIT_FAILURE;
}
else
printf("Device opened\n");

if(libusb_kernel_driver_active(dev, 0) == 1) {
fprintf(stderr, "Kernel driver active\n");
libusb_detach_kernel_driver(dev, 0);
}

ret = libusb_claim_interface(dev, 0);
if(ret < 0) {
fprintf(stderr, "Couldn't claim interface\n");
return EXIT_FAILURE;
}

// To maintain our sample rate
struct timespec ts;
ts.tv_sec = 0;
ts.tv_nsec = 2000000;

memset(&rframe, 0, sizeof(frame));
if (loadild(argv[1], rframe) < 0)
{
fprintf(stderr, "Failed to load ILDA\n");
return EXIT_FAILURE;
}

while(1)
{
process();

if(nanosleep(&ts, NULL) != 0)
fprintf(stderr, "Nanosleep failed");
ret = libusb_bulk_transfer(dev, (1 | LIBUSB_ENDPOINT_OUT), (unsigned char*)&outBuffer, 256, &actual, 0);
if(ret != 0 || actual != 256)
fprintf(stderr, "Write error\n");
}

libusb_release_interface(dev, 0);
libusb_close(dev);
libusb_exit(ctx);

return 0;
}







В функции main() с помощью nanosleep также регулируется периодичность, с которой микроконтроллеру посылаются новые данные.

Полностью исходный код прошивки контроллера можно посмотреть на GitHub.

Планы на будущее




В дальнейшем планируется-таки доделать сие до состояния, похожего на изначально задумывавшуюся лазерную арфу. Для этого достаточно одного, а не двух зеркал, так как лазерный луч двигается только вдоль одной оси. Принцип работы арфы заключается в том, что контроллер зажигает и гасит луч лазера в известные ему моменты времени, создавая лазерную «клавиатуру» в воздухе. Исполнитель, перекрывая рукой в светоотражающей перчатке яркий луч лазера, приводит в действие фоточувствительный элемент в основании «арфы». Так как микроконтроллер знает, в какой момент какую часть клавиатуры он «рисовал», то может определить какой из лучей был перекрыт. Дальше дело за формированием соответствующего MIDI-сообщения и отправке его в компьютер или подключенный аппаратный синтезатор для формирования звука.

This entry passed through the Full-Text RSS service — if this is your content and you're reading it on someone else's site, please read the FAQ at http://ift.tt/jcXqJW.


[Перевод - recovery mode ] Техника Помидора по-русски

Прочитав статью хабрапользователя Rdnk начал изучать разные GTD подходы и натолкнулся на Технику Помидора (название зацепило). Прочитав методику, мне она показалась достаточно занимательной. Есть варианты на итальянском, английском, китайском, а на русском нет — я подумал, что было бы неплохо иметь русский перевод, и не найдя его рещил перевести сам, и сильно неспешно переводил аж 3 года :)

Для программистов она боюсь не сильно подходит, но для тех кому приходится сталкиваться с большим количеством «отвлеканий» может подойти.

В процессе перевода натолкнулся на то, что некоторые вещи непросто перевести — например interruption. Перевести просто как прерывание — наверное неправильно, притом что такое слово может вызвать у хабрааудитории совсем другие ассоциации из мира ПО :) поэтому решил наименовать это отвлеканиями. Хоть и нет в русском языке такого слова, но в данном конкретном контексте мне показалось перевести так наиболее близким по смыслу.

В целом, замечания и комментарии приветствуются.

P.S. Это первый мой опыт перевода, так что — не обессудьте :)


This entry passed through the Full-Text RSS service — if this is your content and you're reading it on someone else's site, please read the FAQ at http://ift.tt/jcXqJW.


[recovery mode] Персональный ROADAR

Соавтор и идейный вдохновитель проекта RoadAR Марат Башлыков опирался на свою собственную потребность замечать знаки на дороге. Много путешествуя на автомобиле, он обратил внимание, что водитель далеко не всегда видит знаки, а это грозит штрафами и в целом повышает опасность вождения. С другой стороны, у многих есть видеорегистратор, камера которого способна фиксировать знаки, и телефон, который может обрабатывать данные с камеры. Так и появилась идея создать RoadAR. В прошлом году проект участвовал в акселерационной программе GenerationS, прошел в финал конкурса Web Ready, а в этом году стал победителем на конференции Startup Village в номинации Intel и собирается представлять Россию на конкурсе Intel Global Challenge в Калифорнии.

С.К.: Марат, расскажите, как работает RoadAR?


М.Б.: RoadAR (прим.: телефон, оснащенный приложением RoadAR goo.gl/yC6F9t) ставится на держатель в машину, запускается и начинает записывать видео, параллельно анализируя изображение алгоритмами компьютерного зрения. На современном смартфоне он с частотой 30 кадров в секунду обнаруживает и распознает дорожные знаки, понимает зону их действия и предупреждает водителя в случае нарушения или о возможной опасности. Сложностей здесь много: заставить смартфон параллельно записывать видео и анализировать его уже не просто, а нам нужно еще накладывать на видео координаты (т.е. микшировать его), производить распознавание, да еще так, чтобы это работало на огромном парке android устройств. Самая большая проблема сейчас – это энергопотребление, но скоро мы рассчитываем его значительно снизить за счет оптимизации работы алгоритмов распознавания.


С.К.: Вы используете какие-то сторонние разработки?


М.Б.: Мы используем OpenCV для некоторых базовых преобразований и операций, но многое пишем сами, чтобы заставить это работать достаточно быстро на мобильных устройствах. Очень много работы сделано в области вычислений на GPU, но пока мы его не подключаем из-за того же энергопотребления.


С.К.: С какой точностью работает система? Что влияет на качество распознавания?


М.Б.: Есть 2 ключевых момента в распознавании знаков (если считать, что смартфон довольно мощный и у него хорошая камера) – детектирование кандидата в знак и, собственно, само распознавание. Естественно, в случае со смартфоном, мы не можем пробегать окошком по всему кадру и искать там знаки. Сейчас мы ищем подходящие формы и при их нахождении отдаем их «распознавалке». Мы добились быстрого поиска базовых форм, но единственное ограничение сейчас – они должны быть замкнутыми. Т.е. перекрытие зачастую мешает найти форму, а вот тень – нет. На GPU получается искать любые формы и достаточно быстро, но энергопотребление вырастает еще сильнее. Сейчас плотно работаем над быстрым алгоритмом поиска форм на CPU, на который не так сильно влияло бы перекрытие.


Точность же распознавания кандидатов для большинства знаков весьма высокая, для каких-то это 99,7%, для каких-то 95%, но, конечно, есть и трудности. К примеру, знак «уступи дорогу» — он очень часто путается с проводами и мачтами линий электропередач. Дело в том, что это единственный знак, который является перевернутым треугольником и у него нет никаких особенных признаков, по которым его можно было бы отличить и за которые зацепился бы алгоритм. У нас есть много идей, как эту проблему можно решить, сейчас занимаемся их тестированием.


С.К.: Как построена модель монетизации?


М.Б.: Весь основной функционал мы делаем бесплатным. Сейчас думаем о создании нескольких дополнительных фишек за деньги или за share, например — предупреждение о светофорах и ямах. Также мы можем собирать много информации, которая интересна разным бизнесам. Информация с рекламных щитов, цены на заправках и т.д. Еще мы собираем специализированные знаки для грузового транспорта, это такие знаки как «ограничение массы», «ограничение высоты», «ограничение массы, приходящейся на ось транспортного средства» и др., «движение грузовых автомобилей запрещено». Вся эта информация необходима для составления оптимального маршрута и логистические компании уже интересовались у нас подобными данными. Можно собирать большое количество различной информации – о пробках, авариях, качестве дорожной инфраструктуры.


Еще одна идея — это реклама. Звуковая реклама, которая должна быть интересна водителю. К примеру, утром и вечером Вы останавливаетесь у детского сада, следовательно, у Вас есть ребенок и Вам может быть интересна реклама детских товаров, соответственно, при подъезде к детскому миру вы услышите предложение от магазина, да еще и содержащее скидку. Реклама может быть полезной и ее не должно быть много.


С.К.: Расскажите немного о команде проекта?


М.Б.: Команда у нас небольшая, 5 человек. Мы с Евгением много ездим на машинах, по прошлой работе часто мотались в командировки, а сейчас часто ездим на соревнования в другие города, и всегда на машинах. Столкнулись с тем, что современные гаджеты не до конца используют свои возможности. Постоянно думали и обсуждали о том, как можно их улучшить. Решили, что шаг за шагом сможем многое сделать сами, а данные для картографии сможем собирать краудсорсингом. Уволились с работы, собрали команду и сели за работу. Евгений позвал к нам своего бывшего однокурсника Андрея, у которого на тот момент уже был свой успешный бизнес, он работал на аутсорс с США и Австралией, делал высоконагруженные решения. Его тоже заинтересовала наша идея, причем настолько, что он оставил свой бизнес партнерам и пришел к нам в команду.


Еще два очень крутых парня — Фоат и Саша. Фоат — специалист по компьютерному зрению и машинному обучению, его мы искали долго. Ходили по ВУЗам общались с профессорами, они советовали нам своих студентов, но кто-то боялся оставить свое насиженное место, кто-то не подходил нам по другим причинам. И когда мы встретили Фоата, он проникся идеей, причем он сам не водитель, ему стало просто интересно сделать, то, что делаем мы.


А Сашу мы встретили по чистой случайности, так сказать, стечение обстоятельств: в Казанском IT парке проходила ярмарка вакансий; мы на нее особо не надеялись, но уже ближе к завершению к нам подошел молодой парень, сказал, что не знает чем может быть нам полезен, но ему интересно попилить такую штуку. Так с нами и работает теперь, без него мы как без рук :)

В самом начале нам все говорили, что то, что мы задумали, сделать невозможно, смартфоны не справятся с распознаванием. Для нас это стало неким вызовом, и мы теперь периодически доказываем, что невозможного ничего нет, особенно когда это делает такая слаженная команда!


С.К.: Каким образом вам удалось найти инвестиции?


М.Б.: С инвестициями у нас большие проблемы. Мы делаем не интернет магазин, где все понятно: воронки продаж, лэндинги, CPA, LTV.

У нас сложная модель монетизации и с технологической стороны все очень наворочено. Видимо, многие инвесторы находят в этом риски. Полгода мы делали все на свои деньги, вложили достаточно крупную сумму личных средств. Потом в нас вложили микроинвестиции три ангела и Бизнес-инкубатор МГУ. Этих денег хватило выпустить официальный релиз и понять, что людям интересно то, что мы делаем. За последнюю неделю мы получили 15К установок. Теперь ищем следующий раунд инвестиций.


С.К.: Расскажите о ваших впечатлениях от участия в GenerationS?


М.Б.: Впечатления самые замечательные — много хороших проектов, интересные спикеры, полезные лекции. В итоге это отличный нетворкинг и возможность пообщаться с представителями крупных компаний, таких как Intel, Яндекс, послушать Давида Яна и Наталью Касперскую.


С.К.: «Куда бежать» молодому стартаперу, у которого есть идея, но нет денег/квалификации, чтобы реализовать ее самостоятельно?


М.Б.: В стену. Куда бы ни пошли, готовьтесь, что перед вами будет стена. Но, если вы верите в свою идею — не сдавайтесь :)

Мы начали с того, что пришли в Бизнес Инкубатор Казанского IT Парка, и это нам очень помогло. Сейчас много интересных акселерационных программ, инкубаторов и т.д. Там можно и проверить свою идею, и найти единомышленников, и, даже, возможно, привлечь небольшие инвестиции на запуск.


Иллюстрации:

http://ift.tt/1kGE8W7

http://ift.tt/ShdNlB


Видео:

http://...http://ift.tt/1kGEbRz


Интервью для конкурса GenerationS брал Сергей Кокарев


This entry passed through the Full-Text RSS service — if this is your content and you're reading it on someone else's site, please read the FAQ at http://ift.tt/jcXqJW.


Phyode W/Me: спортивный браслет с «индикатором здоровья»


Разного рода спортивных гаджетов и «умных» часов сейчас довольно много. Среди всего этого многообразия новые модели порой просто теряются. И разработчики делают все, чтобы их устройства выгодно отличались от остальных.


Кто-то цену снижает, кто-то добавляет разного рода «плюшки», которые могут пригодиться покупателю. Одним из таких, отличающихся от остальных, устройств является и Браслет W / Me от компании Phyode (кстати, название расшифровывается, как Phyode With Me, т.е. устройство, которое всегда с собой).


Основные функции:




  • Данные о сердечном ритме;

  • Данные о частоте дыхания и тренировка дыхательного ритма;




  • Уведомления о сообщениях и входящих звонках на смартфоне;




  • Функция поиска телефона (нажимаем на кнопку, и смартфон подает сигнал);


Все данные представляются в наглядном виде на дисплее смартфона, в соответствующем приложении (о нем немного ниже).


Теперь о том, что можно назвать «изюминкой» браслета, которая позволила устройству набрать нужную сумму инвестиций на Kickstarter.


Дело в том, что браслет определяет общее состояние организма по таким факторам, как частота сердечного ритма, ритмичность дыхания и некоторым другим параметрам (разработчики называют это «анализатором спектра жизни»). После анализа нескольких показателей выдается оценка общего состояния организма, включая психическое состояние (пассивное, пессимистичное, легко возбудимое, тревожное или сбалансированное).


По словам разработчиков, человек должен следить за тем, чтобы оценка была в сфере «сбалансированное состояние» — в таком случае здоровье не подвергается опасности. Если же сердечный ритм или ритм дыхания отклоняются от нормы, устройство выдаст предупреждение.



Ну, а как нарушения исправлять, уже должен думать человек. То ли похудеть, если есть превышение веса, то ли уйти с нервной работы, то ли заняться спортом. В общем, решение за владельцем браслета.



Дополнительные функции:




  • Функция предупреждения об удалении от смартфона;

  • Удаленный спуск для фотокамеры телефона (т.е. ставим где-то смартфон, для создания общей фотографии, например, и фотографируемся все вместе, а нажатие на кнопку браслета инициализирует «спуск затвора» камеры телефона);

  • Выгрузка данных в «облако» W/Me с возможностью анализа всех данных о состоянии организма командой медиков (эта функция пока в стадии «доводки»);


Характеристики браслета


  • Настраиваемый размер обруча;

  • Ширина: 24 мм;

  • Вес: 39 граммов;

  • Модуль беспроводной связи: Bluetooth 4.0

  • Дисплей: точечный LED

  • Время работы от аккумулятора: в среднем неделя;

  • Зарядка: USB

  • Диапазон рабочей температуры: -2 -45 градусов Цельсия (рекомендуется от 0 до 35);


Совместимость:



iOS смартфон/планшет с Bluetooth 4.0 (приложение доступно вот здесь);


  • iPhone 5;

  • iPhone 4S

  • iPad mini

  • iPad с Retina display

  • iPod touch 5 поколения;




Android смартфон/планшет с Bluetooth 4.0 (приложение доступно вот здесь)

Заказать можно либо на сайте производителя за 190 долларов США, либо на сайте компании Medgadgets за 7500 рублей.


This entry passed through the Full-Text RSS service — if this is your content and you're reading it on someone else's site, please read the FAQ at http://ift.tt/jcXqJW.


пятница, 6 июня 2014 г.

Последняя часть пазла полной виртуальной реальности

image

Вчера на кикстартере началась кампания по сбору средств для Control VR — последней не достающей части для костюма виртуальной реальности, а именно высокоточного отслеживания движения рук, кистей и пальцев.


Ссылка на Kickstarter



Так же стоит отметить, частичное отслеживание положения корпуса. Разработчики обещают сделать гибридную систему, сочетающие инерционные датчики и камеру для отслеживания. Таким образом используются плюсы этих методов, и уменьшаются минусы.


image


Очень радуют демки в видео. Особенно впечатляет «Железный человек». Да и в целом, отзывчивость доведена до совершенно нового уровня.


SDK для Unity3d и Unreal engine 4 в комлекте. Дата поставки Dev-kit'ов Декабрь 2014. Кусает только стоимость в 600$, что для среднестатистического юзера будет существенной тратой. Но если представить потенциал этой технологии в купе c релиз версией Oculus Rift, выходит действительно интересная перспектива.


This entry passed through the Full-Text RSS service — if this is your content and you're reading it on someone else's site, please read the FAQ at http://ift.tt/jcXqJW.


Использование конверсии Google Analytics для группирования товаров и перехода на торговую кампанию Google (Часть 1)

image

Для тех, кто еще не в курсе, напоминаем, что недавно Google заявила о переходе с “обычных кампаний с товарными объявлениями на торговые кампании». Поэтому если вы используете традиционную рекламную кампанию, рекомендуем вам поторопиться сменить ее.

В этой статье рассмотрены пользовательские ярлыки, так называемые «группы AdWords» для кампании товарных объявлений и переход на особые ярлыки торговой кампании (о них мы подробнее расскажем во второй части статьи). Статья основана на нескольких источниках (источник1, источник2) и имеет под собой реальный опыт реализации перехода.



Ранее проектом управляла коммерческая организация, которая не использовала пользовательские ярлыки или рекламные группы. Поэтому появилась отличная возможность увеличить эффективность инвестиций клиента, особенно, если учесть, что 70% бюджета ушло на рекламные объявления, а инвестиционный доход оказался невысоким.



На снимке показаны данные отчета AdWords click за последние 30 дней. Даже при анализе данных модели первого взаимодействия показатели остаются ниже, чем средний доход от инвестиций.


Ниже приведено изображение многоканального отчета от Google Analytics, где показаны данные окупаемости затрат на рекламу. Кроме того, у вас появляется несколько способов просмотреть информацию о конверсии.



Естественно, запросы у клиента большие. За все свои кровные, которые он потратил на рекламу, он хочет получать 450% прибыли от инвестиций. Итак, нам необходимо повысить доходность инвестиций кампании при максимальных затратах, чтобы достичь нашей цели – 450% прибыли.


Для начала, несколько слов о том, как читать такие отчеты:


Видео об анализе многоканальных последовательностей:



Понимание различных моделей

В начале метода сравнения модели вы заметите небольшую иконку с тремя точками и переводом строки (|…), за которым следует фраза «Первое действие». Это модель, на основе которой проведен анализ в этой статье. Базовой моделью является «модель последнего действия», кроме того, есть еще несколько вариантов, о которых рассказано ниже.


На самом деле модель – это простое сочетание правил, которые указывают вам, какому каналу взаимодействия присваивается ценность и какая именно ее часть.


Пример сценария: пользователь впервые нашел ваш сайт, используя контекстное объявление (первое взаимодействие), во второй раз посетил сайт через рекламу на стороннем ресурсе (второе взаимодействие), а третий раз он вернулся на сайт с помощью закладки, после чего и совершил покупку.


Модели атрибуции



image

К примеру, в модели Последнего взаимодействия кредит предоставляется последнему каналу, который использовался перед конверсией (прямое посещение)

В модели атрибуции Последний Клик в Adwords ценность присваивается последнему клику в AdWords (контекстное объявление)


Модель Последний непрямой клик игнорирует все прямые посещения и отдает ценность последнему каналу, который был использован до прямого перехода (реклама на стороннем ресурсе)


Использование модели первого взаимодействия подразумевает, что 100% ценности получает первый канал, через который посетитель попал на сайт.


Линейная модель предоставляет одинаковую ценность всем каналам, которые используются на пути к конверсии.


Понимание различных моделей и методов отчетности критически важно для правильного анализа статистической информации и получения реальных данных.


Отслеживание вашего дохода от инвестиций со службой Google Analytics



Синхронизация службы анализа электронной коммерции с аккаунтом Google Analytics позволяет вам проверять данные о рентабельности затрат на рекламу (ROAS), которые отслеживают ваш доход от инвестиций и являются неким аналогом показателя ROI. Это помогает анализировать рентабельность ваших рекламных кампаний и увеличивать эффективность продвижения товаров сети.

Во второй части мы расскажем о создании пользовательских групп товаров и их преобразовании в особые ярлыки торговой кампании, которые полностью соответствуют новым требованиями Google.


This entry passed through the Full-Text RSS service — if this is your content and you're reading it on someone else's site, please read the FAQ at http://ift.tt/jcXqJW.


[Перевод - recovery mode ] SQL Injection для eBay



Хронометраж событий:




  1. Дата обноружения 19/05/2014

  2. Дата баг-репорта eBay: 19/05/2014

  3. Дата баг-фикса: 19/05/2014






В процессе поиска уязвимостей на eBay, я случайно наткнулся на домен 3.ebay.com.au/ и его зеркала imode.ebay.de/, imode.ebay.fr/. Похоже, что это был домен для пользователей телефонов старой "Тройки", но я не уверен. (примечание: Тройка это мобильный оператор который был выкуплен Vodafone)

На третьей строке страницы я нашел ссылку — «Категории». В этом разделе, было несколько выпадающих списков, в которых содержаться «суб-категории» товара (Тот, кто раньше заходил на eBay, поймет о чём я).


Cразу стало ясно, что там будет использовано несколько $_GET параметров, так что я просто поставил апостроф в конце первого параметра «emv_CatParent».

Фантастика, но вернулась не полная страница. Это означало, что передо мной был типичный blind SQL injection.


Далее в ходе исследования уязвимости, я пришел к выводу, что eBay используют Microsoft SQL Server, и это стало для меня проблемой. Так как у меня нет опыта работы с MSDB, пришлось использовать sqlmap и делать всё через него.


Первое что я сделал — просканировал параметр который я нашел, чтобы убедиться, что мое предположение было правильным.


И тут понеслось…

[INFO] GET parameter 'emv_CatParent' is 'Generic UNION query (NULL) - 1 to 10 columns' injectable


И это было не всё:

[01:34:38] [INFO] GET parameter 'emv_CatParent' seems to be 'Microsoft SQL Server/Sybase stacked queries' injectable


А это значит, что была возможность читать и писать файлы. Полистав еще немного имена колонок, я остановил свои исследования и пошел писать баг репорт.


Подборка скринов:





База данных «ebayDB»








Базы данных








Доступные таблицы в «ebayDB».








Спсиок колонок в «payment_old» таблице.








Нет хеша для Admin пользователя?.. А вы я смотрю рисковые парни.




ну и на последок письмо от eBay.


This entry passed through the Full-Text RSS service — if this is your content and you're reading it on someone else's site, please read the FAQ at http://ift.tt/jcXqJW.


Установка Alfresco Community 4.2.f на выделенный виртуальный сервер

Все когда то заканчивается, закончился один, затем и второй триальный период на Jelastic.com. А платить за виртуальный сервер у которого нет полноты управления каталогами и файлами мне так и не захотелось. На меньшей ступени явно не хватит ресурсов, а там где их вдоволь и цена уже кусается.



Несколько комментариев к статье о хостинге и виртуальных серверах заставили меня «оторвать задницу от стула» и заняться поиском подходящего кандидата. Мне повезло и за небольшие деньги я приобрел пару виртуальных выделенных серверов (cloudatcost.com) разной мощности на сумму чуть больше 100 долл. США, за оба, в пожизненное пользование. Ура я избавляюсь от почасовой оплаты загрузки! В душе я понимаю, что это будет пока жива компания провайдер, дай бог ей долгих лет жизни. Оплата через PayPal, еще пару минут ожидания информационного письма и первоначальная установка имиджа Ubuntu Linux 13.10 64-bit не заняла и 10 минут. И вот в моем распоряжении пара серверов 20GB & 40GB с внешним IP.

Альфреску туда и скорее!

Вместо введения

Когда Вы начинаете настройку нового Linux сервера, есть несколько, почти обязательных, шагов конфигурации, которые необходимо сделать до начала основной установки. Это повысит безопасность и удобство использования Вашего сервера и даст Вам прочную основу для всех последующих действий. (Предварительную часть можно пропустить если установку делали Вы сами с инсталляционного диска Ubuntu)


Первый вход в систему

Для первоначальной регистрации (login) на Вашем сервере, Вам необходимо знать внешний IP-адрес сервера и пароль супер- пользователя «root». Используя информацию в электронном письме с необходимыми login/password, входим на страницу администраторской панели сервера, и в закладке INFO смотрим пароль пользователя ”root” и IP-адрес сервера.



Пользователь root — административный пользователь в среде Linux, у которого есть очень широкие полномочия. Именно из-за этих полномочий, настоятельно не рекомендуется использовать аккаунт root для повседневного использования. Объясняется тем, что можно нанести непоправимые повреждения операционной системы и приложений, даже случайно.

Далее несколько несложных действий которые позволят настроить альтернативную учетную запись пользователя с уменьшенным объемом полномочий и предназначенного для повседневной работы. А также несколько советов, как получить увеличенные полномочия в тех случаях, когда Вы реально нуждаетесь в них.

В административной панели есть кнопка позволяющая вызвать в броузере консоль Вашего сервера. Настоящую консоль! Отправив команду CTRL-ALT-DEL из этой консоли (есть справа кнопка) мы можем наблюдать перезагрузку как на обычном сервере. Воспользуемся консолью войдем в систему пользователем root (если у Вас черный экран и нет приглашения, нажмите Enter):



Ввод пароля на экране отображаться не будет, даже перемещением курсора.


Изменить пароль суперпользователя

Вам вряд ли потребуется помнить пароль, который в настоящее время установлен для суперпользователя. Тем не менее, Вы можете изменить пароль на какой то другой с помощью команды:

# passwd<enter>

Потребуется ввести текущий пароль пользователя “root”и подтвердить свой новый пароль. Отображаться на экране ничего при этом не будет.


Создать нового пользователя

Создадим пользователя, который и будет использоваться нами для дальнейшей работы:



Можно не отвечать на вопросы о пользователе, просто нажать несколько раз Enter.

Добавим созданному пользователю «root» полномочия

Теперь добавим вновь созданному пользователю полномочия суперпользователя. Эти полномочия потребуются в ряде случаев при выполнении административных задач.

# adduser alex sudo<enter>

Незамедлительно проверим результат. Для этого выйдем (#exit ) и снова залогинемся вновь созданным пользователем. И с помощью команды (# sudo bash) проверим наши возможности:



Все получилось, при необходимости мы сможем становится суперпользователем.

SSH сервер в системе уже запущен. По умолчанию он на 22 порту. При желании его тоже можно поменять.

На этом завершается предварительная настройка системы.


Настройка PuTTY

Удобнее пользоваться локальной терминальной программой типа PuTTY. Терминальную программу каждый выбирает по собственному вкусу. Я выбрал PuTTY. В конфигурации укажем адрес сервера и номер настроенного порта. Меня устраивает тот факт, что команды в командную строку можно перенести мышкой и по необходимости изменить размер шрифта, конечно и многое другое.


Установка Oracle Java 7

Чтобы установить последнюю версию Oracle JDK7 в Ubuntu, используйте следующие команды:

$ sudo add-apt-repository ppa:webupd8team/java

$ sudo apt-get update

$ sudo apt-get install oracle-java7-installer


(соглашаемся с пользовательской лицензией в открывшемся окне)


Установка Alfresco 4.2.f

Скачиваем дистрибутив для x64 linux версии. Для этого залогинимся вновь созданным пользователем. Сразу после логина мы окажемся в своем домашнем каталоге:

$ pwd > /home/alex

вернуться в него можно командой:

$ cd ~

качаем дистрибутив:

$ wget http://ift.tt/1usFO84

сделаем скаченный файл исполняемым:

$ chmod 755 alfresco-community-4.2.f-installer-linux-x64.bin

ну и запускаем собственно инсталляцию:

$ sudo ./ alfresco-community-4.2.f-installer-linux-x64.bin --mode text

Далее отвечаем на ряд вопросов. Русский язык в консоли лучше не выбирать, будут крокозябры. Выбрав английский Вы ничего не потеряете:



Language Selection

Please select the installation language

[1] English – English

[2] French – Français

[3] Spanish – Español

[4] Italian – Italiano

[5] German – Deutsch

[6] Japanese – 日本語

[7] Dutch – Nederlands

Please choose an option [1] : 1 <Enter>

—————————————————————————-

Welcome to the Alfresco Community Setup Wizard.

—————————————————————————-

Installation Type

[1] Easy – Installs servers with the default configuration

[2] Advanced – Configures server ports and service properties.: Also choose optional components to install.

Please choose an option [1] : 1 <Enter>

—————————————————————————-

Installation folder

Please choose a folder to install Alfresco Community

Select a folder [/opt/alfresco-4.0.d]:<Enter>


Дальше необходимо ввести пароль администратора и подтвердить:

—————————————————————————-

Admin Password

Please give a password to use for the Alfresco administrator account.

Admin Password:


После ввода пароля, хотим ли мы запускать альфреско как сервис с автозапуском?, ответ “Y“

Install as a service

You can optionally register Alfresco Community as a service. This way it will automatically be started every time the machine is started.

Install Alfresco Community as a service? [Y/n]: Y <Enter>


Все готово. Устанавливаем файлы:


Setup is now ready to begin installing Alfresco Community on your computer.

Do you want to continue? [Y/n]: Y<Enter>


Дальше картинка с процентами и градусник:


Please wait while Setup installs Alfresco Community on your computer.

Installing

0% ______________ 50% ______________ 100%


Хотим почитать файл или нет?


Setup has finished installing Alfresco Community on your computer.

View Readme File [Y/n]: N<Enter>


Далее запускать ли сейчас web интерфейс.


Launch Alfresco Community Share [Y/n]: Y<Enter>


После видим что то вроде этого:


Using CATALINA_BASE: /opt/alfresco-4.2.f/tomcat

Using CATALINA_HOME: /opt/alfresco-4.2.f/tomcat

*****

…… tomcat started


Немного подождем, запускаем броузер, заходим по http://наш_ip:8080/share/ и радуемся…

Однако радость наша еще не полная, строчки верхнего меню не видно.

Потребуется еще пара пассов над пациентом. Они описаны в описании заплатки к системе (http://ift.tt/1usFQge):

суть в том, что необходимо заменить имеющийся файл с таким же именем на вот этот файл:


http://ift.tt/1kDEGg9


и даже в двух местах


-/opt/alfresco-4.2.d/tomcat/webapps/share/WEB-INF/lib

-/opt/alfresco-4.2.d/alf_data/solr/lib


Ну и перегрузить:


$ sudo /opt/alfresco-4.2.f/alfresco.sh restart


Вот теперь все на своих местах.


This entry passed through the Full-Text RSS service — if this is your content and you're reading it on someone else's site, please read the FAQ at http://ift.tt/jcXqJW.