@@ -1161,7 +1161,7 @@ packet_to_lease(struct packet *packet)
11611161 lease = malloc (sizeof (struct client_lease ));
11621162
11631163 if (!lease ) {
1164- warning ("dhcpoffer: no memory to record lease. " );
1164+ warning ("dhcpoffer: no memory to record lease" );
11651165 return (NULL );
11661166 }
11671167
@@ -1202,47 +1202,80 @@ packet_to_lease(struct packet *packet)
12021202
12031203 /* If the server name was filled out, copy it.
12041204 Do not attempt to validate the server name as a host name.
1205- RFC 2131 merely states that sname is NUL-terminated (which do
1205+ RFC 2131 merely states that sname is NUL-terminated (which we
12061206 do not assume) and that it is the server's host name. Since
12071207 the ISC client and server allow arbitrary characters, we do
12081208 as well. */
12091209 if ((!packet -> options [DHO_DHCP_OPTION_OVERLOAD ].len ||
12101210 !(packet -> options [DHO_DHCP_OPTION_OVERLOAD ].data [0 ] & 2 )) &&
12111211 packet -> raw -> sname [0 ]) {
12121212 lease -> server_name = malloc (DHCP_SNAME_LEN + 1 );
1213- if (! lease -> server_name ) {
1214- warning ("dhcpoffer: no memory for server name. " );
1213+ if (lease -> server_name == NULL ) {
1214+ warning ("dhcpoffer: no memory for server name" );
12151215 free_client_lease (lease );
12161216 return (NULL );
12171217 }
1218- memcpy (lease -> server_name , packet -> raw -> sname , DHCP_SNAME_LEN );
1219- lease -> server_name [DHCP_SNAME_LEN ]= '\0' ;
1220- if (strchr (lease -> server_name , '"' ) != NULL ||
1221- strchr (lease -> server_name , '\\' ) != NULL ) {
1222- warning ("dhcpoffer: server name contains invalid characters." );
1223- free_client_lease (lease );
1224- return (NULL );
1218+ for (i = 0 ; i < DHCP_SNAME_LEN ; i ++ ) {
1219+ if (packet -> raw -> sname [i ] == '\0' ) {
1220+ break ;
1221+ }
1222+ if (packet -> raw -> sname [i ] < ' ' ||
1223+ packet -> raw -> sname [i ] == '"' ||
1224+ packet -> raw -> sname [i ] == '\\' ) {
1225+ warning ("dhcpoffer: server name contains "
1226+ "unsafe characters" );
1227+ free (lease -> server_name );
1228+ lease -> server_name = NULL ;
1229+ break ;
1230+ }
1231+ lease -> server_name [i ] = packet -> raw -> sname [i ];
1232+ }
1233+ /* Terminate and zero-pad */
1234+ if (lease -> server_name != NULL ) {
1235+ while (i < DHCP_SNAME_LEN + 1 ) {
1236+ lease -> server_name [i ++ ] = '\0' ;
1237+ }
12251238 }
12261239 }
12271240
1228- /* Ditto for the filename . */
1241+ /* Ditto for the file name . */
12291242 if ((!packet -> options [DHO_DHCP_OPTION_OVERLOAD ].len ||
12301243 !(packet -> options [DHO_DHCP_OPTION_OVERLOAD ].data [0 ] & 1 )) &&
12311244 packet -> raw -> file [0 ]) {
12321245 /* Don't count on the NUL terminator. */
12331246 lease -> filename = malloc (DHCP_FILE_LEN + 1 );
1234- if (! lease -> filename ) {
1235- warning ("dhcpoffer: no memory for filename. " );
1247+ if (lease -> filename == NULL ) {
1248+ warning ("dhcpoffer: no memory for file name " );
12361249 free_client_lease (lease );
12371250 return (NULL );
12381251 }
1239- memcpy (lease -> filename , packet -> raw -> file , DHCP_FILE_LEN );
1240- lease -> filename [DHCP_FILE_LEN ]= '\0' ;
1241- if (strchr (lease -> filename , '"' ) != NULL ||
1242- strchr (lease -> filename , '\\' ) != NULL ) {
1243- warning ("dhcpoffer: filename contains invalid characters." );
1244- free_client_lease (lease );
1245- return (NULL );
1252+ for (i = 0 ; i < DHCP_FILE_LEN ; i ++ ) {
1253+ if (packet -> raw -> file [i ] == '\0' ) {
1254+ break ;
1255+ }
1256+ if (packet -> raw -> file [i ] < ' ' ||
1257+ packet -> raw -> file [i ] == '"' ) {
1258+ warning ("dhcpoffer: file name contains "
1259+ "unsafe characters" );
1260+ free (lease -> filename );
1261+ lease -> filename = NULL ;
1262+ break ;
1263+ }
1264+ if (packet -> raw -> file [i ] == '\\' ) {
1265+ /*
1266+ * This is common in Windows-centric
1267+ * environments. Instead of rejecting,
1268+ * silently convert to forward slash.
1269+ */
1270+ packet -> raw -> file [i ] = '/' ;
1271+ }
1272+ lease -> filename [i ] = packet -> raw -> file [i ];
1273+ }
1274+ /* Terminate and zero-pad */
1275+ if (lease -> filename != NULL ) {
1276+ while (i < DHCP_FILE_LEN + 1 ) {
1277+ lease -> filename [i ++ ] = '\0' ;
1278+ }
12461279 }
12471280 }
12481281 return lease ;
0 commit comments