lunes, 17 de marzo de 2014

Cómo instalar ps2pdf en CentOS 6.5

Una herramienta muy útil que empleo para pasar man pages a formato PDF es ps2pdf (contracción de postscript to pdf).

La sintaxis utilizada es la siguiente:

man -t <herramienta> | ps2pdf - herramienta.pdf

donde <herramienta> es el nombre del programa cuyo manual deseo convertir en PDF.

Este proceso involucra dos pasos:

1) Desplegar el manual del programa en formato PostScript.

2) En vez de mostrar la salida por pantalla, redireccionar la misma a ps2pdf, que creará el archivo herramienta.pdf en el directorio donde se esté trabajando.

¿Pero qué hacer si ps2pdf no está instalado en el sistema?

[root@centos ~]# man -t ps | ps2pdf - ps.pdf
bash: ps2pdf: command not found
[root@centos ~]

[root@centos ~]# cat /etc/centos-release
CentOS release 6.5 (Final)
[root@centos ~]#

En ese caso hay que instalar los paquetes ghostscript y ghostscript-fonts. El primero contiene a ps2pdf y el segundo es incluye el conjunto de fuentes que ghostscript utiliza para renderizar texto:

[root@centos ~]# yum info ghostscript ghoscript-fonts
Loaded plugins: fastestmirror
Loading mirror speeds from cached hostfile
 * base: mirrors.dcarsat.com.ar
 * extras: mirrors.dcarsat.com.ar
 * updates: mirror.gtdinternet.com
Available Packages
Name        : ghostscript
Arch        : i686
Version     : 8.70
Release     : 19.el6
Size        : 4.5 M
Repo        : base
Summary     : A PostScript interpreter and renderer
URL         : http://www.ghostscript.com/
License     : GPLv3+ and Redistributable, no modification permitted
Description : Ghostscript is a set of software that provides a PostScript
            : interpreter, a set of C procedures (the Ghostscript library, which
            : implements the graphics capabilities in the PostScript language) and
            : an interpreter for Portable Document Format (PDF) files. Ghostscript
            : translates PostScript code into many common, bitmapped formats, like
            : those understood by your printer or screen. Ghostscript is normally
            : used to display PostScript files and to print PostScript files to
            : non-PostScript printers.
            :
            : If you need to display PostScript files or print them to
            : non-PostScript printers, you should install ghostscript. If you
            : install ghostscript, you also need to install the ghostscript-fonts
            : package.

Name        : ghostscript
Arch        : x86_64
Version     : 8.70
Release     : 19.el6
Size        : 4.4 M
Repo        : base
Summary     : A PostScript interpreter and renderer
URL         : http://www.ghostscript.com/
License     : GPLv3+ and Redistributable, no modification permitted
Description : Ghostscript is a set of software that provides a PostScript
            : interpreter, a set of C procedures (the Ghostscript library, which
            : implements the graphics capabilities in the PostScript language) and
            : an interpreter for Portable Document Format (PDF) files. Ghostscript
            : translates PostScript code into many common, bitmapped formats, like
            : those understood by your printer or screen. Ghostscript is normally
            : used to display PostScript files and to print PostScript files to
            : non-PostScript printers.
            :
            : If you need to display PostScript files or print them to
            : non-PostScript printers, you should install ghostscript. If you
            : install ghostscript, you also need to install the ghostscript-fonts
            : package.

[root@centos ~]#

Procedemos a la instalación de los dos paquetes mencionados anteriormente:

[root@centos ~]# yum install ghostscript ghoscript-fonts
Loaded plugins: fastestmirror
Loading mirror speeds from cached hostfile
 * base: mirrors.dcarsat.com.ar
 * extras: mirrors.dcarsat.com.ar
 * updates: mirror.gtdinternet.com
Setting up Install Process
No package ghoscript-fonts available.
Resolving Dependencies
--> Running transaction check
---> Package ghostscript.x86_64 0:8.70-19.el6 will be installed
--> Processing Dependency: urw-fonts >= 1.1 for package: ghostscript-8.70-19.el6.x86_64
--> Processing Dependency: libpng12.so.0(PNG12_0)(64bit) for package: ghostscript-8.70-19.el6.x86_64
--> Processing Dependency: libjpeg.so.62(LIBJPEG_6.2)(64bit) for package: ghostscript-8.70-19.el6.x86_64
--> Processing Dependency: ghostscript-fonts for package: ghostscript-8.70-19.el6.x86_64
--> Processing Dependency: libpng12.so.0()(64bit) for package: ghostscript-8.70-19.el6.x86_64
--> Processing Dependency: libjpeg.so.62()(64bit) for package: ghostscript-8.70-19.el6.x86_64
--> Processing Dependency: libjasper.so.1()(64bit) for package: ghostscript-8.70-19.el6.x86_64
--> Processing Dependency: libfontconfig.so.1()(64bit) for package: ghostscript-8.70-19.el6.x86_64
--> Processing Dependency: libcupsimage.so.2()(64bit) for package: ghostscript-8.70-19.el6.x86_64
--> Processing Dependency: libcups.so.2()(64bit) for package: ghostscript-8.70-19.el6.x86_64
--> Processing Dependency: libcairo.so.2()(64bit) for package: ghostscript-8.70-19.el6.x86_64
--> Processing Dependency: libXt.so.6()(64bit) for package: ghostscript-8.70-19.el6.x86_64
--> Processing Dependency: libXext.so.6()(64bit) for package: ghostscript-8.70-19.el6.x86_64
--> Processing Dependency: libX11.so.6()(64bit) for package: ghostscript-8.70-19.el6.x86_64
--> Processing Dependency: libSM.so.6()(64bit) for package: ghostscript-8.70-19.el6.x86_64
--> Processing Dependency: libICE.so.6()(64bit) for package: ghostscript-8.70-19.el6.x86_64
--> Running transaction check
---> Package cairo.x86_64 0:1.8.8-3.1.el6 will be installed
--> Processing Dependency: libpixman-1.so.0()(64bit) for package: cairo-1.8.8-3.1.el6.x86_64
--> Processing Dependency: libfreetype.so.6()(64bit) for package: cairo-1.8.8-3.1.el6.x86_64
--> Processing Dependency: libXrender.so.1()(64bit) for package: cairo-1.8.8-3.1.el6.x86_64
---> Package cups-libs.x86_64 1:1.4.2-50.el6_4.5 will be installed
--> Processing Dependency: libgnutls.so.26(GNUTLS_1_4)(64bit) for package: 1:cups-libs-1.4.2-50.el6_4.5.x86_64
--> Processing Dependency: libtiff.so.3()(64bit) for package: 1:cups-libs-1.4.2-50.el6_4.5.x86_64
--> Processing Dependency: libgnutls.so.26()(64bit) for package: 1:cups-libs-1.4.2-50.el6_4.5.x86_64
--> Processing Dependency: libavahi-common.so.3()(64bit) for package: 1:cups-libs-1.4.2-50.el6_4.5.x86_64
--> Processing Dependency: libavahi-client.so.3()(64bit) for package: 1:cups-libs-1.4.2-50.el6_4.5.x86_64
---> Package fontconfig.x86_64 0:2.8.0-3.el6 will be installed
---> Package ghostscript-fonts.noarch 0:5.50-23.1.el6 will be installed
--> Processing Dependency: xorg-x11-font-utils for package: ghostscript-fonts-5.50-23.1.el6.noarch
---> Package jasper-libs.x86_64 0:1.900.1-15.el6_1.1 will be installed
---> Package libICE.x86_64 0:1.0.6-1.el6 will be installed
---> Package libSM.x86_64 0:1.2.1-2.el6 will be installed
---> Package libX11.x86_64 0:1.5.0-4.el6 will be installed
--> Processing Dependency: libX11-common = 1.5.0-4.el6 for package: libX11-1.5.0-4.el6.x86_64
--> Processing Dependency: libxcb.so.1()(64bit) for package: libX11-1.5.0-4.el6.x86_64
---> Package libXext.x86_64 0:1.3.1-2.el6 will be installed
---> Package libXt.x86_64 0:1.1.3-1.el6 will be installed
---> Package libjpeg-turbo.x86_64 0:1.2.1-3.el6_5 will be installed
---> Package libpng.x86_64 2:1.2.49-1.el6_2 will be installed
---> Package urw-fonts.noarch 0:2.4-10.el6 will be installed
--> Running transaction check
---> Package avahi-libs.x86_64 0:0.6.25-12.el6 will be installed
---> Package freetype.x86_64 0:2.3.11-14.el6_3.1 will be installed
---> Package gnutls.x86_64 0:2.8.5-13.el6_5 will be installed
---> Package libX11-common.noarch 0:1.5.0-4.el6 will be installed
---> Package libXrender.x86_64 0:0.9.7-2.el6 will be installed
---> Package libtiff.x86_64 0:3.9.4-10.el6_5 will be installed
---> Package libxcb.x86_64 0:1.8.1-1.el6 will be installed
--> Processing Dependency: libXau.so.6()(64bit) for package: libxcb-1.8.1-1.el6.x86_64
---> Package pixman.x86_64 0:0.26.2-5.1.el6_5 will be installed
---> Package xorg-x11-font-utils.x86_64 1:7.2-11.el6 will be installed
--> Processing Dependency: libfontenc.so.1()(64bit) for package: 1:xorg-x11-font-utils-7.2-11.el6.x86_64
--> Processing Dependency: libXfont.so.1()(64bit) for package: 1:xorg-x11-font-utils-7.2-11.el6.x86_64
--> Running transaction check
---> Package libXau.x86_64 0:1.0.6-4.el6 will be installed
---> Package libXfont.x86_64 0:1.4.5-3.el6_5 will be installed
---> Package libfontenc.x86_64 0:1.0.5-2.el6 will be installed
--> Finished Dependency Resolution

Dependencies Resolved

========================================================================================================================================================================
 Package                                       Arch                             Version                                         Repository                         Size
========================================================================================================================================================================
Installing:
 ghostscript                                   x86_64                           8.70-19.el6                                     base                              4.4 M
Installing for dependencies:
 avahi-libs                                    x86_64                           0.6.25-12.el6                                   base                               54 k
 cairo                                         x86_64                           1.8.8-3.1.el6                                   base                              309 k
 cups-libs                                     x86_64                           1:1.4.2-50.el6_4.5                              base                              317 k
 fontconfig                                    x86_64                           2.8.0-3.el6                                     base                              186 k
 freetype                                      x86_64                           2.3.11-14.el6_3.1                               base                              359 k
 ghostscript-fonts                             noarch                           5.50-23.1.el6                                   base                              751 k
 gnutls                                        x86_64                           2.8.5-13.el6_5                                  updates                           346 k
 jasper-libs                                   x86_64                           1.900.1-15.el6_1.1                              base                              136 k
 libICE                                        x86_64                           1.0.6-1.el6                                     base                               53 k
 libSM                                         x86_64                           1.2.1-2.el6                                     base                               37 k
 libX11                                        x86_64                           1.5.0-4.el6                                     base                              584 k
 libX11-common                                 noarch                           1.5.0-4.el6                                     base                              192 k
 libXau                                        x86_64                           1.0.6-4.el6                                     base                               24 k
 libXext                                       x86_64                           1.3.1-2.el6                                     base                               35 k
 libXfont                                      x86_64                           1.4.5-3.el6_5                                   updates                           136 k
 libXrender                                    x86_64                           0.9.7-2.el6                                     base                               30 k
 libXt                                         x86_64                           1.1.3-1.el6                                     base                              184 k
 libfontenc                                    x86_64                           1.0.5-2.el6                                     base                               24 k
 libjpeg-turbo                                 x86_64                           1.2.1-3.el6_5                                   updates                           174 k
 libpng                                        x86_64                           2:1.2.49-1.el6_2                                base                              182 k
 libtiff                                       x86_64                           3.9.4-10.el6_5                                  updates                           343 k
 libxcb                                        x86_64                           1.8.1-1.el6                                     base                              110 k
 pixman                                        x86_64                           0.26.2-5.1.el6_5                                updates                           200 k
 urw-fonts                                     noarch                           2.4-10.el6                                      base                              3.1 M
 xorg-x11-font-utils                           x86_64                           1:7.2-11.el6                                    base                               75 k

Transaction Summary
========================================================================================================================================================================
Install      26 Package(s)

Total download size: 12 M
Installed size: 37 M
Is this ok [y/N]: Y

Luego de presionar Enter, la instalación comienza y continúa su curso:

Downloading Packages:
(1/26): avahi-libs-0.6.25-12.el6.x86_64.rpm                                                                                                      |  54 kB     00:00    
(2/26): cairo-1.8.8-3.1.el6.x86_64.rpm                                                                                                           | 309 kB     00:00    
(3/26): cups-libs-1.4.2-50.el6_4.5.x86_64.rpm                                                                                                    | 317 kB     00:00    
(4/26): fontconfig-2.8.0-3.el6.x86_64.rpm                                                                                                        | 186 kB     00:00    
(5/26): freetype-2.3.11-14.el6_3.1.x86_64.rpm                                                                                                    | 359 kB     00:01    
(6/26): ghostscript-8.70-19.el6.x86_64.rpm                                                                                                       | 4.4 MB     00:10    
(7/26): ghostscript-fonts-5.50-23.1.el6.noarch.rpm                                                                                               | 751 kB     00:01    
(8/26): gnutls-2.8.5-13.el6_5.x86_64.rpm                                                                                                         | 346 kB     00:00    
(9/26): jasper-libs-1.900.1-15.el6_1.1.x86_64.rpm                                                                                                | 136 kB     00:00    
(10/26): libICE-1.0.6-1.el6.x86_64.rpm                                                                                                           |  53 kB     00:00    
(11/26): libSM-1.2.1-2.el6.x86_64.rpm                                                                                                            |  37 kB     00:00    
(12/26): libX11-1.5.0-4.el6.x86_64.rpm                                                                                                           | 584 kB     00:01    
(13/26): libX11-common-1.5.0-4.el6.noarch.rpm                                                                                                    | 192 kB     00:00    
(14/26): libXau-1.0.6-4.el6.x86_64.rpm                                                                                                           |  24 kB     00:00    
(15/26): libXext-1.3.1-2.el6.x86_64.rpm                                                                                                          |  35 kB     00:00    
(16/26): libXfont-1.4.5-3.el6_5.x86_64.rpm                                                                                                       | 136 kB     00:00    
(17/26): libXrender-0.9.7-2.el6.x86_64.rpm                                                                                                       |  30 kB     00:00    
(18/26): libXt-1.1.3-1.el6.x86_64.rpm                                                                                                            | 184 kB     00:00    
(19/26): libfontenc-1.0.5-2.el6.x86_64.rpm                                                                                                       |  24 kB     00:00    
(20/26): libjpeg-turbo-1.2.1-3.el6_5.x86_64.rpm                                                                                                  | 174 kB     00:00    
(21/26): libpng-1.2.49-1.el6_2.x86_64.rpm                                                                                                        | 182 kB     00:00    
(22/26): libtiff-3.9.4-10.el6_5.x86_64.rpm                                                                                                       | 343 kB     00:01    
(23/26): libxcb-1.8.1-1.el6.x86_64.rpm                                                                                                           | 110 kB     00:00    
(24/26): pixman-0.26.2-5.1.el6_5.x86_64.rpm                                                                                                      | 200 kB     00:00    
(25/26): urw-fonts-2.4-10.el6.noarch.rpm                                                                                                         | 3.1 MB     00:08    
(26/26): xorg-x11-font-utils-7.2-11.el6.x86_64.rpm                                                                                               |  75 kB     00:00    
------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Total                                                                                                                                   326 kB/s |  12 MB     00:38    
Running rpm_check_debug
Running Transaction Test
Transaction Test Succeeded
Running Transaction
  Installing : libjpeg-turbo-1.2.1-3.el6_5.x86_64                                                                                                                  1/26
  Installing : freetype-2.3.11-14.el6_3.1.x86_64                                                                                                                   2/26
  Installing : fontconfig-2.8.0-3.el6.x86_64                                                                                                                       3/26
  Installing : libICE-1.0.6-1.el6.x86_64                                                                                                                           4/26
  Installing : 2:libpng-1.2.49-1.el6_2.x86_64                                                                                                                      5/26
  Installing : libSM-1.2.1-2.el6.x86_64                                                                                                                            6/26
  Installing : libfontenc-1.0.5-2.el6.x86_64                                                                                                                       7/26
  Installing : libXfont-1.4.5-3.el6_5.x86_64                                                                                                                       8/26
  Installing : 1:xorg-x11-font-utils-7.2-11.el6.x86_64                                                                                                             9/26
  Installing : ghostscript-fonts-5.50-23.1.el6.noarch                                                                                                             10/26
  Installing : urw-fonts-2.4-10.el6.noarch                                                                                                                        11/26
  Installing : libtiff-3.9.4-10.el6_5.x86_64                                                                                                                      12/26
  Installing : jasper-libs-1.900.1-15.el6_1.1.x86_64                                                                                                              13/26
  Installing : avahi-libs-0.6.25-12.el6.x86_64                                                                                                                    14/26
  Installing : libXau-1.0.6-4.el6.x86_64                                                                                                                          15/26
  Installing : libxcb-1.8.1-1.el6.x86_64                                                                                                                          16/26
  Installing : libX11-common-1.5.0-4.el6.noarch                                                                                                                   17/26
  Installing : libX11-1.5.0-4.el6.x86_64                                                                                                                          18/26
  Installing : libXrender-0.9.7-2.el6.x86_64                                                                                                                      19/26
  Installing : libXt-1.1.3-1.el6.x86_64                                                                                                                           20/26
  Installing : libXext-1.3.1-2.el6.x86_64                                                                                                                         21/26
  Installing : pixman-0.26.2-5.1.el6_5.x86_64                                                                                                                     22/26
  Installing : cairo-1.8.8-3.1.el6.x86_64                                                                                                                         23/26
  Installing : gnutls-2.8.5-13.el6_5.x86_64                                                                                                                       24/26
  Installing : 1:cups-libs-1.4.2-50.el6_4.5.x86_64                                                                                                                25/26
  Installing : ghostscript-8.70-19.el6.x86_64                                                                                                                     26/26
  Verifying  : libtiff-3.9.4-10.el6_5.x86_64                                                                                                                       1/26
  Verifying  : gnutls-2.8.5-13.el6_5.x86_64                                                                                                                        2/26
  Verifying  : libXfont-1.4.5-3.el6_5.x86_64                                                                                                                       3/26
  Verifying  : libfontenc-1.0.5-2.el6.x86_64                                                                                                                       4/26
  Verifying  : libSM-1.2.1-2.el6.x86_64                                                                                                                            5/26
  Verifying  : fontconfig-2.8.0-3.el6.x86_64                                                                                                                       6/26
  Verifying  : jasper-libs-1.900.1-15.el6_1.1.x86_64                                                                                                               7/26
  Verifying  : urw-fonts-2.4-10.el6.noarch                                                                                                                         8/26
  Verifying  : freetype-2.3.11-14.el6_3.1.x86_64                                                                                                                   9/26
  Verifying  : 1:xorg-x11-font-utils-7.2-11.el6.x86_64                                                                                                            10/26
  Verifying  : ghostscript-fonts-5.50-23.1.el6.noarch                                                                                                             11/26
  Verifying  : pixman-0.26.2-5.1.el6_5.x86_64                                                                                                                     12/26
  Verifying  : libXrender-0.9.7-2.el6.x86_64                                                                                                                      13/26
  Verifying  : 1:cups-libs-1.4.2-50.el6_4.5.x86_64                                                                                                                14/26
  Verifying  : libX11-common-1.5.0-4.el6.noarch                                                                                                                   15/26
  Verifying  : libxcb-1.8.1-1.el6.x86_64                                                                                                                          16/26
  Verifying  : 2:libpng-1.2.49-1.el6_2.x86_64                                                                                                                     17/26
  Verifying  : libjpeg-turbo-1.2.1-3.el6_5.x86_64                                                                                                                 18/26
  Verifying  : libXt-1.1.3-1.el6.x86_64                                                                                                                           19/26
  Verifying  : libXau-1.0.6-4.el6.x86_64                                                                                                                          20/26
  Verifying  : ghostscript-8.70-19.el6.x86_64                                                                                                                     21/26
  Verifying  : libICE-1.0.6-1.el6.x86_64                                                                                                                          22/26
  Verifying  : libX11-1.5.0-4.el6.x86_64                                                                                                                          23/26
  Verifying  : libXext-1.3.1-2.el6.x86_64                                                                                                                         24/26
  Verifying  : cairo-1.8.8-3.1.el6.x86_64                                                                                                                         25/26
  Verifying  : avahi-libs-0.6.25-12.el6.x86_64                                                                                                                    26/26

Installed:
  ghostscript.x86_64 0:8.70-19.el6                                                                                                                                     

Dependency Installed:
  avahi-libs.x86_64 0:0.6.25-12.el6         cairo.x86_64 0:1.8.8-3.1.el6               cups-libs.x86_64 1:1.4.2-50.el6_4.5    fontconfig.x86_64 0:2.8.0-3.el6         
  freetype.x86_64 0:2.3.11-14.el6_3.1       ghostscript-fonts.noarch 0:5.50-23.1.el6   gnutls.x86_64 0:2.8.5-13.el6_5         jasper-libs.x86_64 0:1.900.1-15.el6_1.1 
  libICE.x86_64 0:1.0.6-1.el6               libSM.x86_64 0:1.2.1-2.el6                 libX11.x86_64 0:1.5.0-4.el6            libX11-common.noarch 0:1.5.0-4.el6      
  libXau.x86_64 0:1.0.6-4.el6               libXext.x86_64 0:1.3.1-2.el6               libXfont.x86_64 0:1.4.5-3.el6_5        libXrender.x86_64 0:0.9.7-2.el6         
  libXt.x86_64 0:1.1.3-1.el6                libfontenc.x86_64 0:1.0.5-2.el6            libjpeg-turbo.x86_64 0:1.2.1-3.el6_5   libpng.x86_64 2:1.2.49-1.el6_2          
  libtiff.x86_64 0:3.9.4-10.el6_5           libxcb.x86_64 0:1.8.1-1.el6                pixman.x86_64 0:0.26.2-5.1.el6_5       urw-fonts.noarch 0:2.4-10.el6           
  xorg-x11-font-utils.x86_64 1:7.2-11.el6 

Complete!
[root@centos ~]#

Por la paciencia demostrada al seguir este post hasta este punto, comparto una perlita muy útil que podemos utilizar para localizar en qué paquete está contenida una cierta herramienta que deseemos instalar (que fue la que usé yo para localizar a ps2pdf):

[root@centos ~]# yum provides "*/ps2pdf"
Loaded plugins: fastestmirror
Loading mirror speeds from cached hostfile
 * base: mirrors.dcarsat.com.ar
 * extras: mirrors.dcarsat.com.ar
 * updates: mirror.gtdinternet.com
base/filelists_db                                                                                                                                | 5.9 MB     00:13    
extras/filelists_db                                                                                                                              |  11 kB     00:00    
updates/filelists_db                                                                                                                             | 1.3 MB     00:02    
ghostscript-8.70-19.el6.i686 : A PostScript interpreter and renderer
Repo        : base
Matched from:
Filename    : /usr/bin/ps2pdf

ghostscript-8.70-19.el6.x86_64 : A PostScript interpreter and renderer
Repo        : base
Matched from:
Filename    : /usr/bin/ps2pdf

[root@centos ~]#

miércoles, 15 de enero de 2014

Cálculo de diferencia entre dos fechas en Oracle 11g

El WMS que utiliza la empresa para la que trabajo provee -entre muchas otras cosas- la posibilidad de mostrar el tiempo de carga de los camiones que se envían con producto terminado a los clientes a partir del cálculo de la diferencia entre el momento en el que se ingresan el primer y último pallet en los mismos. Sin embargo, muestra este dato en un formato decimal en vez de hh:mm (que es más "amigable" y entendible a primera vista).

Por ejemplo:

2.0representa2:00
1.51:30
1.21:12

El proceso de modificación se llevó a cabo en dos partes: 1) Convertir la diferencia de fechas al formato hh:mi, y 2) Asegurar que la los minutos representados por un dígito (1 a 9) se muestren con un cero al principio (01...09).

CONVERTIR LA DIFERENCIA DE FECHAS AL FORMATO HH24:MI

Voy a llamar a la fecha inicial como start_date y a la fecha final como end_date, ambas en el formato DD-MON-YY HH24:MI.

Como punto de partida, es importante tener en cuenta que al realizar la diferencia entre dos fechas en Oracle 11g,


el resultado entregado es el equivalente en días:


En primer lugar multiplicamos la diferencia por 24 para obtener el número de horas correspondiente


(también redondeamos a dos dígitos decimales el resultado):

Ahora separamos la parte entera del resultado anterior como horas y a los dos dígitos decimales los convertimos a su equivalente en minutos:



Podemos ir un paso más allá y solamente tomar la parte entera de la última columna (ya que representa un grado de precisión suficiente) para luego convertir el nuevo resultado a formato de minutos (anteponiendo un cero en el caso de que el número de minutos esté entre 1 y 9).

ASEGURAR QUE LA CANTIDAD DE MINUTOS SE MUESTRE EN EL FORMATO mi


Se utiliza el modelo 'mi' de las funciones TO_DATE y TO_CHAR para representar una cantidad entera comprendida entre 0 y 59 como minutos. Cabe aclarar que si el número en cuestión está fuera de ese rango, cualquiera de las funciones arrojará un error.
La parte entera de las horas se concatena con el equivalente de la parte decimal en minutos mediante el operador "||" utilizando como separador los dos puntos ":".

Documentación de las funciones utilizadas:

miércoles, 25 de diciembre de 2013

Separación de privilegios en OpenSSH

Muchos servicios del sistema operativo requieren privilegios especiales para poder ejecutar sus respectivas tareas. Un error de programación en un servicio que posea tales privilegios abre la puerta para comprometer al sistema mediante la adquisición no autorizada de permisos. En el peor de los casos, un atacante remoto podría alcanzar privilegios de superusuario.
[Mediante la separación de privilegios], aun cuando existan errores en partes no privilegiadas, los mismos no pueden utilizarse para escalar privilegios. [Este procedimiento] es especialmente útil para servicios del sistema que autentican usuarios.
El principio básico de la separación de privilegios consiste en reducir la cantidad de código que se ejecuta con permisos especiales sin afectar o limitar la funcionalidad del servicio. Esto se logra al dividir una aplicación en dos o más partes: una de ellas (denominada monitor) es ejecutada con privilegios y la/s otra/s (esclavo/s) sin ellos. Esto disminuye la exposición a bugs en el código que es ejecutado con privilegios. Idealmente, la única consecuencia que resulta de un error en un servicio que esté corriendo con separación de privilegios es la denegación del servicio al atacante mismo.
La línea del archivo de configuración de sshd que habilita la separación de privilegios es la siguiente:
Con esta configuración, estos son los procesos relacionados con ssh:
La salida del comando ps -ef muestra los siguientes datos:
  1. UID (User ID)
  2. PID (Process ID)
  3. PPID (Parent Process ID)
  4. C (Tiempo de CPU utilizado recientemente por el proceso, en términos de ciclos de reloj, más información aquí)
  5. STIME (Start TIME)
  6. TTY (terminal en la que está corriendo el proceso, una ? indica que el proceso es un daemon que está ejecutándose en segundo plano)
  7. TIME (tiempo de CPU utilizado por el proceso desde que fue iniciado, en términos de minutos y segundos)
  8. CMD (argumentos de la línea de comandos que iniciaron el proceso)
En la imagen anterior vemos que el demonio ssh (PID 3287) fue iniciado por init (PID 1). A su vez, sshd inició el monitor (parte de la aplicación que posee privilegios, PID 3354), el cual luego de la autenticación hizo lo propio con la sesión de usuario remota (PID 3430) creando una pseudo-terminal para la misma.
Este ejemplo muestra dos operaciones que requieren privilegios de superusuarios en la máquina remota:
  • Antes de la autenticación, el monitor es la parte de la aplicación que chequea la contraseña provista por el usuario (o la clave pública) contra el archivo de contraseñas (/etc/shadow) o contra la clave pública del cliente previamente guardada en el servidor, según corresponda. Si la autenticación es exitosa, se crea la sesión de usuario; caso contrario, se niega el acceso.
  • Después de la autenticación, se crea una pseudo-terminal para la sesión de usuario.
De esta manera, el monitor y el esclavo corren separadamente y se reduce considerablemente la posibilidad de un ataque por escalación de privilegios.
Ahora voy a deshabilitar la separación de privilegios y reiniciar el servidor ssh, para luego verificar los procesos nuevamente:
En este caso podemos ver que tanto sshd como el monitor fueron iniciados directamente por init, y aunque se lanzó la sesión remota de usuario correctamente, no se dispone de la "interfaz" de protección entre las peticiones efectuadas y la aplicación con privilegios. De esta manera, si un atacante lograra encontrar un bug en el código, podría fácilmente explotarla para escalar privilegios sobre el sistema.
Sin embargo, se puede ver en este caso que el monitor retuvo su PID y solamente cambiaron los correspondientes al esclavo y a sshd. Al inspeccionar el estado de los procesos luego de finalizar la conexión anterior e iniciar una nueva, podemos ver lo siguiente:
Por último, vuelvo a editar el archivo /etc/ssh/sshd_config para volver a utilizar separación de privilegios (recordar que más allá de reiniciar el servidor ssh, los cambios recién serán aplicados a la próxima conexión):

Nota: La teoría de este post está basado en el paper "Preventing Privilege Escalation" por Niels Provos, Markus Friedl, y Peter Honeyman, el cual puede descargarse desde este link.

martes, 24 de diciembre de 2013

Contenido de /proc (Parte 1)

El directorio /proc contiene varios archivos y subdirectorios que muestran información sobre el kernel, incluso los recursos del sistema que están siendo utilizados. Dichos archivos y directorios no son "reales" (el tamaño en disco que acusan es 0) sino que representan una especie de "ventana" que permite observar qué está sucediendo en el kernel en un momento dado. En otras palabras, el directorio /proc puede verse como el centro de control e información del kernel. Para más detalles, se puede consultar su man page.
Esta publicación, y las que siguen, serán llevadas a cabo sobre un servidor casero con Debian Wheezy 7.2 y kernel 3.2.0-4-686-pae:
Un listado del contenido de /proc nos muestra lo siguiente (en azul los directorios, en cyan los enlaces simbólicos, y en blanco los archivos):
Lo que primero nos llama la atención es que hay varios directorios cuyo nombre es un número (1, 10, 12, 13, 3284, etc). Los mismos reciben el nombre de directorios de proceso debido a que están relacionados con el PID de un cierto proceso y contienen información específica sobre el mismo. El usuario y el grupo que figuran como dueños de cada directorio son los mismos que el usuario y el grupo bajo los que está corriendo dicho proceso.
Cuando un proceso finaliza su ejecución, o es terminado, su directorio asociado dentro de /proc desaparece.
Por ejemplo, voy a buscar el PID que corresponde a mi sesión de usuario (conexión por ssh) desde la PC cliente que estoy usando para conectarme al servidor:
Puedo ver que dentro del directorio /proc hay un subdirectorio 3695, y el contenido del mismo es el siguiente:
Algunos de los archivos más interesantes dentro del mismo son los siguientes:
  • cmdline: contiene los argumentos de la línea de comandos que se utilizaron para iniciar el proceso.
  • cwd: es un enlace al directorio actual del proceso.
  • exe: es un enlace al ejecutable del proceso.
  • status: muestra el estado del proceso de una manera más "amigable".

Más información:

jueves, 12 de diciembre de 2013

Web form con html5, php, jQuery, archivos adjuntos y MySQL como RDBMS

Para que un formulario html permita la carga de archivos adjuntos debe tener seteado el siguiente atributo:

<form method="post" action="cargar.php" enctype="multipart/form-data">

Html5 brinda, entre muchas otras innovaciones, la posibilidad de agregar controles de contenido del tipo number que permiten fijar valores iniciales, mínimos y máximos, e intervalos de salto:



Si se necesita utilizar una lista desplegable que permita la selección de varios ítems de manera simultánea, se debe agregar el atributo multiple="multiple" e indicar que el resultado de la selección estará compuesto por un arreglo de elementos:

<select name="partes[]" multiple="multiple">


Para que el archivo cargar.php pueda procesar estos valores correctamente, se le debe indicar que separe los elementos provenientes del formulario con un separador a nuestra elección. En el caso siguiente se muestra el uso de la coma-espacio para cumplir esta función:

join(', ', $_POST['partes'])

Resultando en:
Cabeza, Cuello, Hombro

(Se puede asignar el resultado de esa función a una variable que posteriormente será la que se utilice para la consulta SQL).

Para evitar errores al ingresar fechas y horas, se puede utilizar el excelente plugin de jQuery escrito por Trent Richardson (distribuido bajo licencia GPL). El siguiente ejemplo utiliza la función datetimepicker para desplegar un calendario con fecha y hora, o con almanaque solamente, cuando un control con id datetime o class datepicker recibe foco, respectivamente (debe colocarse dentro de los tags de head):


Ejemplo de calendario con fecha y hora

Ejemplo de calendario con fecha únicamente

El formato de la fecha puede preformatearse mediante Javascript en el lado del cliente (ver ejemplo anterior) o hacerse posteriormente en el lado del servidor utilizando PHP utilizando las funciones date y strtotime (string to time):
$fecha_accion1 = date("Y-m-d H:i:s", strtotime($_POST['fecha_accion1']));

miércoles, 16 de octubre de 2013

Actualización de Debian Wheezy 7.2

El día 12 de octubre de 2013 el proyecto Debian anunció la disponibilidad inmediata de la segunda actualización de la versión 7, Debian Wheezy 7.2, la cual de por sí no representa una nueva versión del sistema operativo, sino una actualización estable propiamente dicha de varios paquetes contenidos en Wheezy.
Esta publicación muestra los pasos que seguí para actualizar mi server a partir de las instrucciones que se brindan en el sitio oficial del proyecto.
Primero mostramos la versión actual del sistema operativo:


Agregamos las siguientes fuentes al archivo /etc/apt/sources.list (líneas 9 y 10):


Tras lo cual procedemos a actualizar la lista de los paquetes disponibles con el comando aptitude update y el sistema en sí con aptitude dist-upgrade (el cual por razones históricas todavía continúa siendo un sinónimo de aptitude full-upgrade, de acuerdo al man page de aptitude):

Luego de llevar a cabo el proceso, volvemos a consultar la versión actual del sistema operativo:

lunes, 29 de julio de 2013

Administración de usuarios en Linux (Parte 1): Agregar usuarios y análisis de los archivos /etc/passwd y /etc/shadow

Para agregar un usuario en un sistema Linux, nos logueamos como root y utilizamos el comando
adduser <nombre_de_usuario>
A continuación, podemos llenar la información solicitada (la cual es opcional salvo la contraseña) para identificar mejor al usuario que estamos creando (es decir, para poder relacionarlo con una persona real):


Dicha información es almacenada en dos archivos:
/etc/passwd

Como podemos ver, cada línea de este archivo representa el registro que contiene la información correspondiente a cada usuario, y está compuesta por 7 campos (separados por ":"), a saber:
1) Nombre de usuario
2) ¿Encriptar la clave y guardar la versión encriptada en el archivo /etc/shadow? (Una "x" indica que este proceso se lleva a cabo, mientras que cualquier otro caracter -generalmente "*" se utiliza para deshabilitar la cuenta). Cabe destacar que por razones de seguridad, solamente se guarda la contraseña encriptada. Cuando un usuario intenta loguearse en el sistema se encripta la clave que ingresa y se compara con la almacenada en /etc/shadow; si ambas son iguales se permite el acceso al mismo.
En mi experiencia, quitar la "x" del segundo campo es una forma de permitir el login sin contraseña de un usuario local del sistema (se puede utilizar este método para recuperar el acceso como root si no se conoce la contraseña del superusuario. Para esto obviamente es necesario disponer de acceso físico al equipo y utilizar una herramienta de booteo tal como un LiveCD/DVD/USB que permita montar los sistemas de archivos locales y modificar la línea correspondiente en el archivo /etc/passwd).
¡CUIDADO CON ESTO! Ya que cuando se cambie la contraseña del usuario en cuestión, ya sea que lo haga él mismo utilizando el comando passwd o que lo haga el superusuario, la nueva contraseña se almacenará encriptada en el archivo /etc/passwd (el cual pueden leer todos los usuarios). Esto representa un serio problema de seguridad:

Si se llegase a utilizar el método descrito para cambiar la contraseña de root, o si se desea permitir el login local sin contraseña, antes de cambiar la contraseña del usuario en cuestión, se debe volver a colocar la "x" en su lugar, para luego proceder a cambiar la clave normalmente:


3) ID de usuario. El UID 0 es el perteneciente a root, desde el 1 hasta el 999 están reservados para usuarios del sistema (procesos o daemons), y desde 1000 en adelante se utilizan para los usuarios "comunes" o locales del sistema.
4) ID de grupo primario (GID). El GID 0 es el perteneciente a root, desde el 1 hasta el 999 están reservados para usuarios del sistema (procesos o daemons), y desde 1000 en adelante se utilizan para los usuarios "comunes" o locales del sistema. Se guarda en el archivo /etc/group. En Linux, los grupos representan un segundo anillo de seguridad en lo que a permisos respecta.
5) Información del usuario
6) El home (directorio personal) del usuario. Este es el directorio en el que se encontrará el usuario cuando ingrese al sistema. Si este campo está vacío, "/" (raíz del sistema de archivos) se convierte en el directorio personal del usuario.
7) Ruta absoluta a un comando o shell que utilizará el usuario al loguearse (no tiene que ser precisamente un shell, pero de no ser así el sistema no tendrá mucha utilidad).
Podemos ver en la línea n° 6 del primer paste que durante el proceso de creación de un usuario, se copian a su home los archivos que se encuentran en el directorio /etc/skel, que se utilizarán para guardar las preferencias del perfil del usuario (.profile), de su entorno de shell (.bashrc), y de las acciones a realizar cuando cierra sesión (.bash_logout). Adicionalmente se creará dentro del home del usuario el archivo .bash_history en el que se registrará el historial de comandos del mismo:

/etc/shadow
En este archivo se guardan, entre otras cosas (como veremos a continuación) las contraseñas encriptadas de los usuarios:


Otra vez nos encontramos con un registro por línea, con campos separados por ":". El significado de los mismos es el siguiente:
1) Nombre de usuario
2) Contraseña encriptada. Un signo "$" al comienzo es indicador que el cifrado se llevó a cabo utilizando el algoritmo MD5.
3) Días transcurridos desde el 1 de enero de 1970 hasta la fecha correspondiente al último cambio de contraseña.
4) Cantidad mínima de días entre cambios de contraseña, es decir, la cantidad de días que restan hasta la fecha en que se permitirá un cambio de contraseña.
5) Cantidad máxima de días (duración) de la contraseña, luego de la cual el usuario tendrá que cambiarla. 6) Advertencia, número de días antes del vencimiento (expiración) de la contraseña en el que se comenzará a mostrar un mensaje de advertencia avisando de la necesidad de cambiarla.
7) Deshabilitación de cuenta, número de días luego del vencimiento de la clave en que se deshabilitará la cuenta.
8) Cuenta deshabilitada, número de días transcurridos desde el 1 de enero de 1970 hasta el día que la cuenta fue deshabilitada.

¿Por qué los datos de los usuarios se guardan en un archivo y las contraseñas en otro? La razón es que si el archivo en el que se guardan las claves pudiera ser leído por cualquier usuario, se tendría acceso a las contraseñas (encriptadas, sí, pero acceso al fin) y eso representaría un grave problema de seguridad ya que eventualmente podrían ser descifradas con relativa facilidad si no se cuenta con una política de cambio y fortaleza de claves adecuada.
Para demostrar este hecho, utilizando la herramienta john the ripper intentamos crackear la contraseña del usuario recién creado, y vemos que el proceso consume una gran parte de los recursos del sistema (cosa que no es mayor problema si se cuenta con un equipo dedicado a esta tarea).

Precisamente en el segundo campo se puede ver la contraseña del usuario jperez (1234):
(aunque el proceso para crackear una contraseña tan simple duró 44 minutos, hay que tener en cuenta que esto demuestra que SÍ SE PUEDE LOGRAR, y el tiempo se puede disminuir utilizando un equipo que cuente con mayores recursos de hardware). Esta prueba fue realizada en PC Compaq Presario ("modelo" 2000) con 256 MB de RAM y procesador Intel Celeron de 566 MHz.