2019年8月18日 星期日

禁止普通使用者查看dmesg資訊

Source:

dmesg能夠輸出kernel ring buffer中的內容,這些內容中可能會包含一些敏感資訊。

根據 kernel docs 中的說明:


This toggle indicates whether unprivileged users are prevented from using dmesg(8) to view messages from the kernel’s log buffer. When dmesg_restrict is set to (0) there are no restrictions. When dmesg_restrict is set set to (1), users must have CAP_SYSLOG to use dmesg(8). The kernel config option CONFIG_SECURITY_DMESG_RESTRICT sets the default value of dmesg_restrict.

我們可以通過設置內核參數 dmesg_restrict 為 1 的方式來禁止普通使用者查看demsg資訊


sudo sysctl -w kernel.dmesg_restrict=1

我們來看一下現在 dmesg_restrict 的值是什麼


sysctl kernel.dmesg_restrict

kernel.dmesg_restrict = 1

現在再來用普通用戶執行demsg:


[lujun9972@T520 wikit.docker]$ dmesg

dmesg: 讀取內核緩衝區失敗: 不允許的操作

會發現提示無法讀取內核緩衝區

要讓該設置永久生效,則需要修改 /etc/sysctl.conf 文件


sudo echo 'kernel.dmesg_restrict=1' >> /etc/sysctl.conf

libconfig (一) 使用指南

Source: https://blog.csdn.net/crazyhacking/article/details/9668981

20130731 16:28:46 crazyhacking 
版權聲明:本文為博主原創文章,遵循 CC 4.0 by-sa 版權協定,轉載請附上原文出處連結和本聲明。
本文連結:https://blog.csdn.net/crazyhacking/article/details/9668981
官網:http://www.hyperrealm.com/libconfig/


1 libconfig是什麼?
Libconfig是一個結構化的設定檔庫,它可以定義一些設定檔,例如test.cfg . 它比xml可讀性更好,而且更簡潔。而且不像xml,它是 type-aware類型自我感知的,因此不需要做string parsing (分詞?). ini太弱。



2 設定檔說明(摘自手冊翻譯)

libconfig支援結構化、層次化的配置。這些配置可以從檔中讀取或寫入檔,也可以在記憶體中操作。

一個配置由一組setting構成,setting由名字(name)關聯,並有相應的值(value)。一個值(value)可以是以下任意一種類型:

標量值(scalarvalue):整型、64位整型、浮點數、布林值或者字串

陣列(array):一組標量值的序列,所有的標量值必須為同一類型

群組(group):多個setting的集合

列表(list):一組值(value)的序列,各個值可(value)以分別為不同的類型,其他的列表也可以包含其中。



觀察下面這一個層次化GUI應用程式的設定檔,它闡明了一個設定檔語法所有的元素。



#Exampleapplicationconfigurationfile

version="1.0";

application:

{

window:

{

title="MyApplication";

size={w=640;h=480;};

pos={x=350;y=250;};

};

list=(("abc",123,true),1.234,(/*anemptylist*/));

books=(

{

title="TreasureIsland";

author="RobertLouisStevenson";

price=29.95;

qty=5;

},

{

title="SnowCrash";

author="NealStephenson";

price=9.99;

qty=8;

}

);

misc:

{

pi=3.141592654;

bigint=9223372036854775807L;

columns=["LastName","FirstName","MI"];

bitmask=0x1FC3;

};

};





包含在配置中的某個setting可以用path來唯一定義,path用點號分隔連接多個名字(name),由最頂層的群組(group)開始,到setting自身結束。path中的每個名字都是一個setting的名字;如果這個setting沒有名字,那是因為它是陣列(array)或清單(list)中的一個元素。用方括號包含一個整型索引值可以用來表示它的名字。

舉個例子,在上面這個多層的設定檔中,名為xsetting,指向它的path就是application.window.pos.x;名為versionsetting,指向它的path就是很簡單的version;指向book列表中第2book,名為titlesetting,指向它的path就是application.books.[1].title

一個值(value)的資料類型由它本身的格式所決定。

如果一個值用雙引號圍住,那它被認為是一個字串;

如果它看起來是一個整型或浮點數,那它就被認為是整型或浮點數;

如果它是TRUEFALSEtruefalse中的某個,那它就被認為是布林值(TRUEFALSE大小寫不敏感,比如tRuEfALse也被看作為TRUEFALSE);

如果在方括號中包含了多個逗號分隔的值,那它就被認為是陣列;

如果在圓括號中包含了多個逗號分隔的值,那它就被認為是列表;

任何值如果不符合上述的標準,則會被認為是無效並且產生一個分析錯誤。

所有的名字(name)都是大小寫敏感的,並且只能由數位字母、橫杠(-),下橫杠(_)和星號(*)組成,而且必須以字母或星號開頭。其他字元都是非法的。

CC++中,整型、64位整型、浮點數和字串分別被映射為intlonglongdoubleconstchar *。布林型在C中被映射為int,在C++中被映射為bool



下面的章節會從更多的細節方面描述設定檔語法的各個元素。

setting

一個setting的格式如下:

name= value;

或者

name: value;

結尾的分號是必須要有的,空白字元會被忽略;

value可以是標量值、陣列、群組或者清單。



群組(group

一個群組的格式如下:

{setting1,setting2, …}

一個群組可以包含任意個setting,但是在群組中,每個setting的名字必須是唯一的。



陣列(array

一個陣列的格式如下:

[value,value, …]

一個陣列可以有零個或者多個元素,但是每個元素都必須是相同類型的標量值。



列表(list

一個列表的格式如下:

(value,value, …)

一個清單可以有零個或者多個元素,而且每個元素可以分別是標量值、陣列、群組或其他列表。



整型值

整型值(int)可以用兩種方式表示:十進位數字,由0-9組成,並且可以帶+-;十六進位數,0x打頭並且用十六進位數表示。



64位整型值

64位整型值(longlong)表示方法和整型值基本一致,但是需要在最後加上L來表明它是一個64位整型值。比如0L表示一個64位的0值。



浮點值

浮點值由一個十進位數字,可以帶正負符號,然後帶上一個可選的指數。這個可選的指數又由字母E或者e加上一個可選的正負符號再加上具體的數位。



布林值

布林值的取值只能是truefalse,包括另外大小寫混合的寫法,比如tRueFaLSe



字串

字串是由雙引號引起來的任意文本。字串裡的雙引號由轉義符\”替代,其他的轉義符比如\\\f\r\n\t都可以被辨認,並且與通常的理解一致。

另外,轉義符\x也被支持。它後面必須跟上剛好兩個十六進位數,用來表示8位的ASCII值,比如\xFF表示值為0xFFASCII碼。

其他的轉義符都不被支持。

相鄰的兩個字串會被自動連接,就像C的編碼規則一樣。在把一個很長得字串格式化為很短的字串的時候,就會很有用。比如,下面三種寫法的字串都是等價的。



"Thequickbrownfoxjumpedoverthelazydog."



"Thequickbrownfox"

"jumpedoverthelazydog."



"Thequick"/*注釋*/"brownfox"//其他注釋

"jumpedoverthelazydog."



注釋

在設定檔中允許三種類型的注釋

腳本風格的注釋:從#開始到行尾的內容都為注釋。

C風格的注釋:/**/之間的內容,即使是跨行的,都被認為是注釋。

C++風格的注釋:從//開始到行尾的內容都被認為是注釋。

如預料的一樣,注釋符在雙引號字串中出現,會被認為是字串的文本而不是注釋符。

在讀取配置的時候,注釋內容會被忽略,它們不會被認為是配置的一部分。因此,如果配置回寫到檔中,原設定檔中的一些注釋會丟失。



包含指令

一個設定檔可能包含了另外一個設定檔的內容,這時就要用到包含指令。這個指令產生的效果就是在包含點內聯了那個檔的內容。

一個包含指令必須出現在它所在的那一行中,格式如下:

@include“filename”

檔案名中反斜線和雙引號必須用轉義符\\\”來替代。

舉例說明,觀察下面兩個設定檔

#file:quote.cfg

quote="Criticismmaynotbeagreeable,butitisnecessary."

"Itfulfilsthesamefunctionaspaininthehuman"

"body.Itcallsattentiontoanunhealthystateof"

"things.\n"

"\t--WinstonChurchill";



#file:test.cfg

info:{

name="WinstonChurchill";

@include"quote.cfg"

country="UK";

};

包含檔最大只能嵌套10層,突破這個限制會產生一個分析錯誤。

與注釋類似,包含指令也不是設定檔句法的一部分。包含指令在設定檔被分析之前就已經被處理了。因此,當配置回寫回檔的時候,包含指令不會被保留。目前還不支援讓程式把包含指令插入到設定檔中。



3C++版本的api說明
簡單介紹幾個重要的c++ 函數,完整版請參考官網。

說明參數為char *版本的對應也有 參數為string版本的

bool lookupValue (const char *path, int &value) 這個函數重載,參數2為各種類型的

These are convenience methods for looking up the value of a setting with the given path. If the setting is found and is of an appropriate type, the value is stored in value and the method returns true. Otherwise, value is left unmodified and the method returns false. These methods do not throw exceptions.
例子

int var1;
          double var2;
          const char *var3;
         
          if(config.lookupValue("values.var1", var1)
             && config.lookupValue("values.var2", var2)
             && config.lookupValue("values.var3", var3))
          {
            // use var1, var2, var3
          }
          else
          {
            // error handling here
          }



Method on Config: Setting & lookup (const std::string &path)
Method on Config: Setting & lookup (const char * path)
These methods locate the setting specified by the path path. If the requested setting is not found, a SettingNotFoundException is thrown.

Method on Config: bool exists (const std::string &path)
Method on Config: bool exists (const char *path)
These methods test if a setting with the given path exists in the configuration. They return true if the setting exists, and false otherwise. These methods do not throw exceptions.

settings可以直接唄轉化為各種類型(我們知道lookup返回的是路徑)

The following examples demonstrate this usage:

          long width = config.lookup("application.window.size.w");
         
          bool splashScreen = config.lookup("application.splash_screen");
         
          std::string title = config.lookup("application.window.title");

Method on Setting: bool lookupValue (const char *name, bool &value)
Method on Setting: bool lookupValue (const std::string &name, bool &value)
Method on Setting: bool lookupValue (const char *name, int &value)
Method on Setting: bool lookupValue (const std::string &name, int &value)

These are convenience methods for looking up the value of a child setting with the given name. If the setting is found and is of an appropriate type, the value is stored in value and the method returns true. Otherwise, value is left unmodified and the method returns false. These methods do not throw exceptions.


    int var1;
          double var2;
          const char *var3;
         
          if(setting.lookupValue("var1", var1)
             && setting.lookupValue("var2", var2)
             && setting.lookupValue("var3", var3))
          {
            // use var1, var2, var3
          }
          else
          {
            // error handling here
          }




Method on Setting: Setting & add (const std::string &name, Setting::Type type)
Method on Setting: Setting & add (const char *name, Setting::Type type)
These methods add a new child setting with the given name and type to the setting, which must be a group. They return a reference to the new setting. If the setting already has a child setting with the given name, or if the name is invalid, a SettingNameException is thrown. If the setting is not a group, aSettingTypeException is thrown.

Once a setting has been created, neither its name nor type can be changed.

Method on Setting: Setting & add (Setting::Type type)
This method adds a new element to the setting, which must be of type TypeArray or TypeList. If the setting is an array which currently has zero elements, the type parameter (which must be TypeInt, TypeInt64, TypeFloat, TypeBool, or TypeString) determines the type for the array; otherwise it must match the type of the existing elements in the array.

The method returns the new setting on success. If type is a scalar type, the new setting will have a default value of 0, 0.0, false, or NULL, as appropriate.

The method throws a SettingTypeException if the setting is not an array or list, or if type is invalid.

Method on Setting: void remove (const std::string &name)
Method on Setting: void remove (const char *name)
These methods remove the child setting with the given name from the setting, which must be a group. Any child settings of the removed setting are recursively destroyed as well.

If the setting is not a group, a SettingTypeException is thrown. If the setting does not have a child setting with the given name, aSettingNotFoundException is thrown.

Method on Setting: void remove (unsigned int index)
This method removes the child setting at the given index index from the setting, which must be a group, list, or array. Any child settings of the removed setting are recursively destroyed as well.

If the setting is not a group, list, or array, a SettingTypeException is thrown. If index is out of range, a SettingNotFoundException is thrown.

Method on Setting: const char * getName ()
This method returns the name of the setting, or NULL if the setting has no name. Storage for the returned string is managed by the library and released automatically when the setting is destroyed; the string must not be freed by the caller. For safety and convenience, consider assigning the return value to astd::string.

Method on Setting: std::string getPath ()
This method returns the complete dot-separated path to the setting. Settings which do not have a name (list and array elements) are represented by their index in square brackets.

Method on Setting: Setting & getParent ()
This method returns the parent setting of the setting. If the setting is the root setting, a SettingNotFoundException is thrown.

Method on Setting: bool isRoot ()
This method returns true if the setting is the root setting, and false otherwise.

Method on Setting: int getIndex ()
This method returns the index of the setting within its parent setting. When applied to the root setting, this method returns -1.

Method on Setting: Setting::Type getType ()
This method returns the type of the setting. The Setting::Type enumeration consists of the following constants: TypeInt, TypeInt64, TypeFloat,TypeString, TypeBoolean, TypeArray, TypeList, and TypeGroup.

Method on Setting: Setting::Format getFormat ()
Method on Setting: void setFormat (Setting::Format format)
These methods get and set the external format for the setting.

The Setting::Format enumeration consists of the following constants: FormatDefault and FormatHex. All settings support the FormatDefault format. The FormatHex format specifies hexadecimal formatting for integer values, and hence only applies to settings of type TypeInt and TypeInt64. If format is invalid for the given setting, it is ignored.

Method on Setting: bool exists (const std::string &name)
Method on Setting: bool exists (const char *name)
These methods test if the setting has a child setting with the given name. They return true if the setting exists, and false otherwise. These methods do not throw exceptions.

Method on Setting: int getLength ()
This method returns the number of settings in a group, or the number of elements in a list or array. For other types of settings, it returns 0.

Method on Setting: bool isGroup ()
Method on Setting: bool isArray ()
Method on Setting: bool isList ()
These convenience methods test if a setting is of a given type.

Method on Setting: bool isAggregate ()
Method on Setting: bool isScalar ()
Method on Setting: bool isNumber ()
These convenience methods test if a setting is of an aggregate type (a group, array, or list), of a scalar type (integer, 64-bit integer, floating point, boolean, or string), and of a number (integer, 64-bit integer, or floating point), respectively.

Method on Setting: const char * getSourceFile ()
This function returns the name of the file from which the setting was read, or NULL if the setting was not read from a file. This information is useful for reporting application-level errors. Storage for the returned string is managed by the library and released automatically when the configuration is destroyed; the string must not be freed by the caller.

Method on Setting: unsigned int getSourceLine ()
This function returns the line number of the configuration file or stream at which the setting setting was read, or 0 if no line number is available. This information is useful for reporting application-level errors.